예제 #1
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiSetEventHandler(
    PFILE_OBJECT FileObject,
    LONG EventType,
    PVOID Handler,
    PVOID Context)
/*
 * FUNCTION: Sets or resets an event handler
 * ARGUMENTS:
 *     FileObject = Pointer to file object
 *     EventType  = Event code
 *     Handler    = Event handler to be called when the event occurs
 *     Context    = Context input to handler when the event occurs
 * RETURNS:
 *     Status of operation
 * NOTES:
 *     Specify NULL for Handler to stop calling event handler
 */
{
    PDEVICE_OBJECT DeviceObject;
    IO_STATUS_BLOCK Iosb;
    KEVENT Event;
    PIRP Irp;

    AFD_DbgPrint(MAX_TRACE, ("Called\n"));

    if (!FileObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad file object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

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

    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER,   /* Sub function */
                                           DeviceObject,            /* Device object */
                                           FileObject,              /* File object */
                                           &Event,                  /* Event */
                                           &Iosb);                  /* Status */
    if (!Irp)
        return STATUS_INSUFFICIENT_RESOURCES;



    TdiBuildSetEventHandler(Irp,
                            DeviceObject,
                            FileObject,
                            NULL,
                            NULL,
                            EventType,
                            Handler,
                            Context);

    return TdiCall(Irp, DeviceObject, &Event, &Iosb);
}
예제 #2
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiQueryDeviceControl(
    PFILE_OBJECT FileObject,
    ULONG IoControlCode,
    PVOID InputBuffer,
    ULONG InputBufferLength,
    PVOID OutputBuffer,
    ULONG OutputBufferLength,
    PULONG Return)
/*
 * FUNCTION: Queries a device for information
 * ARGUMENTS:
 *     FileObject         = Pointer to file object
 *     IoControlCode      = I/O control code
 *     InputBuffer        = Pointer to buffer with input data
 *     InputBufferLength  = Length of InputBuffer
 *     OutputBuffer       = Address of buffer to place output data
 *     OutputBufferLength = Length of OutputBuffer
 * RETURNS:
 *     Status of operation
 */
{
    PDEVICE_OBJECT DeviceObject;
    IO_STATUS_BLOCK Iosb;
    NTSTATUS Status;
    KEVENT Event;
    PIRP Irp;

    if (!FileObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad file object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

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

    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    Irp = IoBuildDeviceIoControlRequest(IoControlCode,
                                        DeviceObject,
                                        InputBuffer,
                                        InputBufferLength,
                                        OutputBuffer,
                                        OutputBufferLength,
                                        FALSE,
                                        &Event,
                                        &Iosb);
    if (!Irp)
        return STATUS_INSUFFICIENT_RESOURCES;

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

    if (Return)
        *Return = Iosb.Information;

    return Status;
}
예제 #3
0
BOOLEAN KTdiStreamSocket::Unbind()
{
  //KLocker locker(&m_KSynchroObject);

  BOOLEAN         bRes = TRUE;
  PIRP            pIrp = NULL, pIrpError = NULL;
  PDEVICE_OBJECT  pDeviceObject;
  NTSTATUS        NtStatus;
  IO_STATUS_BLOCK IoStatusBlock;

  __try
  {
    if (m_bOpen == TRUE && m_bBind == TRUE && m_bConnected == FALSE && m_bListen == FALSE)
    {
      bRes = FALSE;

      pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject);
      
      pIrp = TdiBuildInternalDeviceControlIrp(
                    TDI_DISASSOCIATE_ADDRESS, 
                    pDeviceObject, 
                    m_pTdiConnectionObject,
                    NULL, 
                    NULL);
      pIrpError = pIrp;
      if (pIrp != NULL)
      {
        TdiBuildDisassociateAddress(
               pIrp, 
               pDeviceObject, 
               m_pTdiConnectionObject,
               NULL,
               NULL);
        
        pIrpError = NULL;
        NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock);
        if (NT_SUCCESS(NtStatus))
        {
          m_bBind = FALSE;
          bRes = TRUE;
        }
        else
        {
          DbgPrint ("TdiUnbind: ERROR (%08x)!!!\n", NtStatus);
        }
      }
    }
  }
  __finally
  {
   if (pIrpError != NULL)
     IoFreeIrp(pIrpError);
  }

  return bRes;
}
예제 #4
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiListen(
    PIRP *Irp,
    PFILE_OBJECT ConnectionObject,
    PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
    PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo,
    PIO_COMPLETION_ROUTINE  CompletionRoutine,
    PVOID CompletionContext)
/*
 * FUNCTION: Listen on a connection endpoint for a connection request from a remote peer
 * ARGUMENTS:
 *     CompletionRoutine = Routine to be called when IRP is completed
 *     CompletionContext = Context for CompletionRoutine
 * RETURNS:
 *     Status of operation
 *     May return STATUS_PENDING
 */
{
    PDEVICE_OBJECT DeviceObject;

    AFD_DbgPrint(MAX_TRACE, ("Called\n"));

    ASSERT(*Irp == NULL);

    if (!ConnectionObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

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

    *Irp = TdiBuildInternalDeviceControlIrp(TDI_LISTEN,              /* Sub function */
                                            DeviceObject,            /* Device object */
                                            ConnectionObject,        /* File object */
                                            NULL,                    /* Event */
                                            NULL);                   /* Status */
    if (*Irp == NULL)
        return STATUS_INSUFFICIENT_RESOURCES;

    TdiBuildListen(*Irp,                   /* IRP */
                   DeviceObject,           /* Device object */
                   ConnectionObject,       /* File object */
                   CompletionRoutine,      /* Completion routine */
                   CompletionContext,      /* Completion routine context */
                   0,                      /* Flags */
                   *RequestConnectionInfo, /* Request connection information */
                   *ReturnConnectionInfo);  /* Return connection information */

    TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, NULL);

    return STATUS_PENDING;
}
예제 #5
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiConnect(
    PIRP *Irp,
    PFILE_OBJECT ConnectionObject,
    PTDI_CONNECTION_INFORMATION ConnectionCallInfo,
    PTDI_CONNECTION_INFORMATION ConnectionReturnInfo,
    PIO_COMPLETION_ROUTINE CompletionRoutine,
    PVOID CompletionContext)
/*
 * FUNCTION: Connect a connection endpoint to a remote peer
 * ARGUMENTS:
 *     ConnectionObject = Pointer to connection endpoint file object
 *     RemoteAddress    = Pointer to remote address
 * RETURNS:
 *     Status of operation
 */
{
    PDEVICE_OBJECT DeviceObject;

    AFD_DbgPrint(MAX_TRACE, ("Called\n"));

    ASSERT(*Irp == NULL);

    if (!ConnectionObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

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

    *Irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT,             /* Sub function */
                                            DeviceObject,            /* Device object */
                                            ConnectionObject,        /* File object */
                                            NULL,                    /* Event */
                                            NULL);                   /* Status */
    if (!*Irp) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    TdiBuildConnect(*Irp,                   /* IRP */
                    DeviceObject,           /* Device object */
                    ConnectionObject,       /* File object */
                    CompletionRoutine,      /* Completion routine */
                    CompletionContext,      /* Completion routine context */
                    NULL,                   /* Time */
                    ConnectionCallInfo,     /* Request connection information */
                    ConnectionReturnInfo);  /* Return connection information */

    TdiCall(*Irp, DeviceObject, NULL, NULL);

    return STATUS_PENDING;
}
예제 #6
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiQueryInformation(
    PFILE_OBJECT FileObject,
    LONG QueryType,
    PMDL MdlBuffer)
/*
 * FUNCTION: Query for information
 * ARGUMENTS:
 *     FileObject   = Pointer to file object
 *     QueryType    = Query type
 *     MdlBuffer    = Pointer to MDL buffer specific for query type
 * RETURNS:
 *     Status of operation
 */
{
    PDEVICE_OBJECT DeviceObject;
    IO_STATUS_BLOCK Iosb;
    KEVENT Event;
    PIRP Irp;

    if (!FileObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad file object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

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

    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    Irp = TdiBuildInternalDeviceControlIrp(TDI_QUERY_INFORMATION,       /* Sub function */
                                           DeviceObject,                /* Device object */
                                           ConnectionObject,            /* File object */
                                           &Event,                      /* Event */
                                           &Iosb);                      /* Status */
    if (!Irp) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    TdiBuildQueryInformation(Irp,
                             DeviceObject,
                             FileObject,
                             NULL,
                             NULL,
                             QueryType,
                             MdlBuffer);

    return TdiCall(Irp, DeviceObject, &Event, &Iosb);
}
예제 #7
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiAssociateAddressFile(
    HANDLE AddressHandle,
    PFILE_OBJECT ConnectionObject)
/*
 * FUNCTION: Associates a connection endpoint to an address file object
 * ARGUMENTS:
 *     AddressHandle    = Handle to address file object
 *     ConnectionObject = Connection endpoint file object
 * RETURNS:
 *     Status of operation
 */
{
    PDEVICE_OBJECT DeviceObject;
    IO_STATUS_BLOCK Iosb;
    KEVENT Event;
    PIRP Irp;

    AFD_DbgPrint(MAX_TRACE, ("Called. AddressHandle (%p)  ConnectionObject (%p)\n",
                             AddressHandle, ConnectionObject));

    if (!ConnectionObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

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

    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    Irp = TdiBuildInternalDeviceControlIrp(TDI_ASSOCIATE_ADDRESS,   /* Sub function */
                                           DeviceObject,            /* Device object */
                                           ConnectionObject,        /* File object */
                                           &Event,                  /* Event */
                                           &Iosb);                  /* Status */
    if (!Irp)
        return STATUS_INSUFFICIENT_RESOURCES;

    TdiBuildAssociateAddress(Irp,
                             DeviceObject,
                             ConnectionObject,
                             NULL,
                             NULL,
                             AddressHandle);

    return TdiCall(Irp, DeviceObject, &Event, &Iosb);
}
예제 #8
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiDisconnect(
    PIRP *Irp,
    PFILE_OBJECT TransportObject,
    PLARGE_INTEGER Time,
    USHORT Flags,
    PIO_COMPLETION_ROUTINE CompletionRoutine,
    PVOID CompletionContext,
    PTDI_CONNECTION_INFORMATION RequestConnectionInfo,
    PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) {
    PDEVICE_OBJECT DeviceObject;

    if (!TransportObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

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

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

    *Irp = TdiBuildInternalDeviceControlIrp(TDI_DISCONNECT,          /* Sub function */
                                            DeviceObject,            /* Device object */
                                            TransportObject,         /* File object */
                                            NULL,                    /* Event */
                                            NULL);                   /* 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 */

    TdiCall(*Irp, DeviceObject, NULL, NULL);

    return STATUS_PENDING;
}
예제 #9
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiReceive(
    PIRP *Irp,
    PFILE_OBJECT TransportObject,
    USHORT Flags,
    PCHAR Buffer,
    UINT BufferLength,
    PIO_COMPLETION_ROUTINE CompletionRoutine,
    PVOID CompletionContext)
{
    PDEVICE_OBJECT DeviceObject;
    PMDL Mdl;

    ASSERT(*Irp == NULL);

    if (!TransportObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    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 */
                                            NULL);                   /* Status */

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

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

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

    _SEH2_TRY {
        AFD_DbgPrint(MID_TRACE, ("probe and lock\n"));
        MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess);
        AFD_DbgPrint(MID_TRACE, ("probe and lock done\n"));
    } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
        AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
        IoFreeMdl(Mdl);
        IoCompleteRequest(*Irp, IO_NO_INCREMENT);
        *Irp = NULL;
        _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES);
    }
    _SEH2_END;

    AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %p\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 */


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

    return STATUS_PENDING;
}
예제 #10
0
파일: tdi.c 프로젝트: hoangduit/reactos
NTSTATUS TdiSendDatagram(
    PIRP *Irp,
    PFILE_OBJECT TransportObject,
    PCHAR Buffer,
    UINT BufferLength,
    PTDI_CONNECTION_INFORMATION Addr,
    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;
    PMDL Mdl;

    ASSERT(*Irp == NULL);

    if (!TransportObject) {
        AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
        return STATUS_INVALID_PARAMETER;
    }

    AFD_DbgPrint(MID_TRACE,("Called(TransportObject %p)\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 */
                                            NULL);                   /* Status */

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

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

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

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

    _SEH2_TRY {
        MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess);
    } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
        AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
        IoFreeMdl(Mdl);
        IoCompleteRequest(*Irp, IO_NO_INCREMENT);
        *Irp = NULL;
        _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES);
    }
    _SEH2_END;

    AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %p\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 */

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

    return STATUS_PENDING;
}
예제 #11
0
/*
BOOLEAN KTdiStreamSocket::Listen(IN USHORT wRemotePort, IN ULONG dwRemoteAddress)
{
  //KLocker locker(&m_KSynchroObject);

  BOOLEAN                      bRes = FALSE;
  PIRP                         pIrp = NULL, pIrpError = NULL;
  PDEVICE_OBJECT               pDeviceObject;
  NTSTATUS                     NtStatus;
  //PTDI_CONNECTION_INFORMATION  pRequestListenInfo = NULL;
  //PTDI_CONNECTION_INFORMATION  pReturnConnectionInfo;
  PTA_IP_ADDRESS               pRequestAddress;
  PTDI_ADDRESS_IP              pIp;
  IO_STATUS_BLOCK              IoStatusBlock;

  __try
  {
    if (m_bOpen == TRUE && m_bBind == TRUE && m_bConnected == FALSE && Disconnect() == TRUE)
    {
      m_nRemotePort = wPort;
      m_nRemoteAddress = dwAddress;

      pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject);
      
      m_pRequestListenInfo = (PTDI_CONNECTION_INFORMATION) new char[2*sizeof(TDI_CONNECTION_INFORMATION) + 2*sizeof(TA_IP_ADDRESS) + sizeof(ULONG)];
      if (m_pRequestListenInfo != NULL)
      {
        memset(m_pRequestListenInfo, 0, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS) + sizeof(ULONG));

        m_pReturnListenInfo = (PTDI_CONNECTION_INFORMATION)((PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS));
        m_pReturnListenInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
        m_pReturnListenInfo->RemoteAddress = (PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION);

        m_pRequestListenInfo->Options = (PVOID) ((PUCHAR)m_pReturnListenInfo + sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS));
        *((ULONG*)(m_pRequestListenInfo->Options)) = TDI_QUERY_ACCEPT;
        m_pRequestListenInfo->OptionsLength = sizeof(ULONG);

        if (m_nRemoteAddress != 0)
        {
          m_pRequestListenInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
          m_pRequestListenInfo->RemoteAddress = (PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION);

          pRequestAddress = (PTA_IP_ADDRESS)(m_pRequestListenInfo->RemoteAddress);
          pRequestAddress->TAAddressCount = 1;
          pRequestAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
          pRequestAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
        
          pIp = (PTDI_ADDRESS_IP)(pRequestAddress->Address[0].Address);
          pIp->sin_port = W_LITTLE_TO_BIG_ENDIAN(m_nRemotePort);
          pIp->in_addr = D_LITTLE_TO_BIG_ENDIAN(m_nRemoteAddress);;
        }
        else
        {
          m_pRequestListenInfo->RemoteAddressLength = 0;
          m_pRequestListenInfo->RemoteAddress = NULL;
        }

        pIrp = TdiBuildInternalDeviceControlIrp(
                      TDI_LISTEN, 
                      pDeviceObject, 
                      m_pTdiConnectionObject,
                      NULL, 
                      NULL);
        pIrpError = pIrp;
        if (pIrp != NULL)
        {
          TdiBuildListen(
                 pIrp, 
                 pDeviceObject, 
                 m_pTdiConnectionObject,
                 NULL, 
                 NULL,
                 TDI_QUERY_ACCEPT, // flags
                 m_pRequestListenInfo,
                 m_pReturnListenInfo);
          
          pIrpError = NULL;
          KeInitializeEvent(&m_kAcceptDestroyEvent, NotificationEvent, FALSE);
          KeInitializeEvent(&m_kListenEvent, NotificationEvent, FALSE);
          pIrp->UserEvent = &m_kListenEvent;
          NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock, FALSE);
          if (NT_SUCCESS(NtStatus))
          {
            DbgPrint ("TdiListen: OK (%08x)!!!\n", NtStatus);
            m_bListen = TRUE;
            bRes = TRUE;
          }
          else
          {
            DbgPrint ("TdiListen: ERROR (%08x)!!!\n", NtStatus);
            delete[] m_pRequestListenInfo;
            m_pRequestListenInfo = NULL;
          }
        }
      }
    }
  }
  __finally
  {
    if (pIrpError != NULL)
      IoFreeIrp(pIrpError);
    if (m_bListen == FALSE && m_pRequestListenInfo != NULL)
      delete[] m_pRequestListenInfo;
  }

  return bRes;
}

BOOLEAN KTdiStreamSocket::Accept(ULONG dwTimeOut)
{
  //KLocker locker(&m_KSynchroObject);

  BOOLEAN                      bRes = FALSE;
  PIRP                         pIrp = NULL, pIrpError = NULL;
  PDEVICE_OBJECT               pDeviceObject;
  NTSTATUS                     NtStatus;
  PTA_IP_ADDRESS               pReturnAddress;
  PTDI_ADDRESS_IP              pIp;
  IO_STATUS_BLOCK              IoStatusBlock;
  PVOID                        pkEvents[2];
  LARGE_INTEGER                TimeOut;
  PLARGE_INTEGER               pTimeOut = NULL;

  //m_KSynchroObject.Lock();

  __try
  {
    if (m_bOpen == TRUE && m_bBind == TRUE && m_bConnected == FALSE && m_bListen == TRUE)
    {
      if (dwTimeOut != 0)
      {
        pTimeOut = &TimeOut;
        TimeOut.QuadPart = dwTimeOut * 10000; // msec -> 100 nsec intervals
        TimeOut.QuadPart = -TimeOut.QuadPart;
      }
      
      pkEvents[0] = &m_kListenEvent;
      pkEvents[1] = &m_kAcceptDestroyEvent;

      NtStatus  = KeWaitForMultipleObjects(2, pkEvents, WaitAny, Suspended, KernelMode, FALSE, pTimeOut, NULL);
      
      if (NtStatus == 0)
      {
        pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject);
      
        pReturnAddress = (PTA_IP_ADDRESS)(m_pReturnListenInfo->RemoteAddress);
        pReturnAddress->TAAddressCount = 1;
        pReturnAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
        pReturnAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
        
        pIrp = TdiBuildInternalDeviceControlIrp(
                      TDI_ACCEPT, 
                      pDeviceObject, 
                      m_pTdiConnectionObject,
                      NULL, 
                      NULL);
        pIrpError = pIrp;
        if (pIrp != NULL)
        {
          TdiBuildAccept(
                 pIrp, 
                 pDeviceObject, 
                 m_pTdiConnectionObject,
                 NULL, 
                 NULL,
                 m_pRequestListenInfo,
                 m_pReturnListenInfo);
          
          pIrpError = NULL;
          NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock, TRUE);
          if (NT_SUCCESS(NtStatus))
          {
            m_bConnected = TRUE;
            bRes = TRUE;
          
            pIp = (PTDI_ADDRESS_IP)(pReturnAddress->Address[0].Address);
            m_nRemotePort = W_BIG_TO_LITTLE_ENDIAN(pIp->sin_port);
            m_nRemoteAddress = D_BIG_TO_LITTLE_ENDIAN(pIp->in_addr);
          
            DbgPrint ("TdiAccept: OK (%08x : %04x)!!!\n", m_nRemoteAddress, m_nRemotePort);
          }
          else
          {
            DbgPrint ("TdiAccept: ERROR (%08x)!!!\n", NtStatus);
          }
        }
      }
    }
  }
  __finally
  {
    if (pIrpError != NULL)
      IoFreeIrp(pIrpError);
  }

  //m_KSynchroObject.UnLock();

  return bRes;
}
*/
ULONG KTdiStreamSocket::Send(PVOID pData, ULONG dwSize)
{
  //KLocker locker(&m_KSynchroObject);

  PIRP                         pIrp = NULL, pIrpError = NULL;
  PMDL                         pMdl;
  PDEVICE_OBJECT               pDeviceObject;
  NTSTATUS                     NtStatus;
  IO_STATUS_BLOCK              IoStatusBlock;
  ULONG                        dwBytesSended = 0;

  //m_KSynchroObject.Lock();

  __try
  {
    if (m_bOpen == TRUE && m_bConnected == TRUE && dwSize != 0)
    {
      pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject);

      pIrp = TdiBuildInternalDeviceControlIrp ( 
                     TDI_SEND,                                       // sub function
                     pDeviceObject,                                  // pointer to device object
                     m_pTdiConnectionObject,                         // pointer to control object
                     NULL,                                           // pointer to event
                     NULL);                                          // pointer to return buffer

      pIrpError = pIrp;
      if (pIrp == NULL)                                              // validate pointer
      {
        NtStatus = STATUS_INSUFFICIENT_RESOURCES;
      }
      else
      {
        pMdl = IoAllocateMdl(
                           pData,                                    // buffer pointer - virtual address
                           dwSize,                                   // length
                           FALSE,                                    // not secondary
                           FALSE,                                    // don't charge quota
                           NULL);                                    // don't use irp
        if (pMdl != NULL)                                            // validate mdl pointer
        {
          __try
          {
            MmProbeAndLockPages(pMdl, KernelMode, IoModifyAccess);    // probe & lock
          } 
          __except(EXCEPTION_EXECUTE_HANDLER)
          {
            DbgPrint("EXCEPTION: MmProbeAndLockPages\n");
            IoFreeMdl(pMdl);
            pMdl = NULL;
          }
        }

        if (pMdl != NULL)
        {
          TdiBuildSend(
                 pIrp, 
                 pDeviceObject,
                 m_pTdiConnectionObject,
                 NULL, 
                 NULL,
                 pMdl, 
                 0,
                 dwSize);
          pIrpError = NULL;

          //m_KSynchroObject.UnLock();

          NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock);

          //m_KSynchroObject.Lock();

          if (NT_SUCCESS(NtStatus))
          {
            dwBytesSended = IoStatusBlock.Information;
          }
          else
          {
            DbgPrint ("TdiSend: ERROR (%08x)!!!\n", NtStatus);
            Disconnect();
          }
        }
      }
    }
예제 #12
0
BOOLEAN KTdiStreamSocket::Disconnect()
{
  //KLocker locker(&m_KSynchroObject);

  BOOLEAN                      bRes = TRUE;
  PIRP                         pIrp = NULL, pIrpError = NULL;
  PDEVICE_OBJECT               pDeviceObject;
  NTSTATUS                     NtStatus;
  PTDI_CONNECTION_INFORMATION  pRequestConnectionInfo = NULL;
  PTDI_CONNECTION_INFORMATION  pReturnConnectionInfo;
  PTA_IP_ADDRESS               pRequestAddress;
  PTDI_ADDRESS_IP              pIp;
  IO_STATUS_BLOCK              IoStatusBlock;

  __try
  {
    if (m_bOpen == TRUE && (m_bConnected == TRUE || m_bListen == TRUE))
    {
      bRes = FALSE;
      
      pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject);
      
      pRequestConnectionInfo = (PTDI_CONNECTION_INFORMATION) new char[sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)];
      if (pRequestConnectionInfo != NULL)
      {
        memset(pRequestConnectionInfo, 0, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS));

        pReturnConnectionInfo = NULL;

        pRequestConnectionInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
        pRequestConnectionInfo->RemoteAddress = (PUCHAR)pRequestConnectionInfo + sizeof(TDI_CONNECTION_INFORMATION);

        pRequestAddress = (PTA_IP_ADDRESS)(pRequestConnectionInfo->RemoteAddress);
        pRequestAddress->TAAddressCount = 1;
        pRequestAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
        pRequestAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
        
        pIp = (PTDI_ADDRESS_IP)(pRequestAddress->Address[0].Address);
        pIp->sin_port = W_LITTLE_TO_BIG_ENDIAN(m_nRemotePort);
        pIp->in_addr = D_LITTLE_TO_BIG_ENDIAN(m_nRemoteAddress);

        pIrp = TdiBuildInternalDeviceControlIrp(
                      TDI_DISCONNECT, 
                      pDeviceObject, 
                      m_pTdiConnectionObject,
                      NULL, 
                      NULL);
        pIrpError = pIrp;
        if (pIrp != NULL)
        {
          TdiBuildDisconnect(
                 pIrp, 
                 pDeviceObject, 
                 m_pTdiConnectionObject,
                 NULL, 
                 NULL,
                 NULL,           // timeout
                 TDI_DISCONNECT_ABORT, //TDI_DISCONNECT_RELEASE,
                 pRequestConnectionInfo,
                 pReturnConnectionInfo);
          
          pIrpError = NULL;

          BOOLEAN bConnected = m_bConnected;
          BOOLEAN bListen = m_bListen;
          
          m_bConnected = FALSE;
          m_bListen = FALSE;

          if (bListen == TRUE)
          {
            KeSetEvent(&m_kAcceptDestroyEvent, 0, FALSE);
            SetEventHandler(TDI_EVENT_CONNECT, (PVOID)NULL, (PVOID)NULL);
          }

          NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock);
          
          if (NT_SUCCESS(NtStatus))
          {
            DbgPrint ("TdiDisconnect: SUCCESS (%08x)!!!\n", NtStatus);
          }
          else
          {
            DbgPrint ("TdiDisconnect: ERROR (%08x)!!!\n", NtStatus);
          }

          if (bConnected == TRUE)
            m_bConnected = FALSE;
          if (bListen == TRUE)
          {
            m_bListen = FALSE;
            delete[] m_pRequestListenInfo;
            m_pRequestListenInfo = NULL;
          }
          bRes = TRUE;
        }
        delete[] pRequestConnectionInfo;
        pRequestConnectionInfo = NULL;
      }
    }
  }
  __finally
  {
    if (pIrpError != NULL)
      IoFreeIrp(pIrpError);
    if (pRequestConnectionInfo != NULL)
      delete[] pRequestConnectionInfo;
  }

  return bRes;
}
예제 #13
0
BOOLEAN KTdiStreamSocket::Connect(IN USHORT wPort, IN ULONG dwAddress, ULONG dwTimeOut)
{
  //KLocker locker(&m_KSynchroObject);

  BOOLEAN                      bRes = FALSE;
  PIRP                         pIrp = NULL, pIrpError = NULL;
  PDEVICE_OBJECT               pDeviceObject;
  NTSTATUS                     NtStatus;
  PTDI_CONNECTION_INFORMATION  pRequestConnectionInfo = NULL;
  PTDI_CONNECTION_INFORMATION  pReturnConnectionInfo;
  PTA_IP_ADDRESS               pRequestAddress;
  PTDI_ADDRESS_IP              pIp;
  IO_STATUS_BLOCK              IoStatusBlock;
  LARGE_INTEGER                TimeOut;
  PLARGE_INTEGER               pTimeOut = NULL;

  __try
  {
    if (m_bOpen == TRUE && m_bBind == TRUE && m_bListen == FALSE && Disconnect() == TRUE)
    {
      m_nRemotePort = wPort;
      m_nRemoteAddress = dwAddress;

      if (dwTimeOut != 0)
      {
        pTimeOut = &TimeOut;
        TimeOut.QuadPart = dwTimeOut * 10000; // msec -> 100 nsec intervals
        TimeOut.QuadPart = -TimeOut.QuadPart;
      }
      
      pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject);
      
      pRequestConnectionInfo = (PTDI_CONNECTION_INFORMATION) new char[sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)];
      if (pRequestConnectionInfo != NULL)
      {
        memset(pRequestConnectionInfo, 0, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS));

        pReturnConnectionInfo = NULL;

        pRequestConnectionInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
        pRequestConnectionInfo->RemoteAddress = (PUCHAR)pRequestConnectionInfo + sizeof(TDI_CONNECTION_INFORMATION);

        pRequestAddress = (PTA_IP_ADDRESS)(pRequestConnectionInfo->RemoteAddress);
        pRequestAddress->TAAddressCount = 1;
        pRequestAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
        pRequestAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
        
        pIp = (PTDI_ADDRESS_IP)(pRequestAddress->Address[0].Address);
        pIp->sin_port = W_LITTLE_TO_BIG_ENDIAN(m_nRemotePort);
        pIp->in_addr = D_LITTLE_TO_BIG_ENDIAN(m_nRemoteAddress);;

        pIrp = TdiBuildInternalDeviceControlIrp(
                      TDI_CONNECT, 
                      pDeviceObject, 
                      m_pTdiConnectionObject,
                      NULL, 
                      NULL);
        pIrpError = pIrp;
        if (pIrp != NULL)
        {
          TdiBuildConnect(
                 pIrp, 
                 pDeviceObject, 
                 m_pTdiConnectionObject,
                 NULL, 
                 NULL,
                 pTimeOut, 
                 pRequestConnectionInfo,
                 pReturnConnectionInfo);
          
          pIrpError = NULL;
          NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock);
          if (NT_SUCCESS(NtStatus))
          {
            m_bConnected = TRUE;
            bRes = TRUE;
          }
          else
          {
            DbgPrint ("TdiConnect: ERROR (%08x)!!!\n", NtStatus);
          }
        }
        delete[] pRequestConnectionInfo;
        pRequestConnectionInfo = NULL;
      }
    }
  }
  __finally
  {
    if (pIrpError != NULL)
      IoFreeIrp(pIrpError);
    if (pRequestConnectionInfo != NULL)
      delete[] pRequestConnectionInfo;
  }

  return bRes;
}