Пример #1
0
NTSTATUS tdi_disconnect(PFILE_OBJECT connectionFileObject, ULONG flags)
{
    PDEVICE_OBJECT  devObj;
    KEVENT          event;
    PIRP            irp;
    IO_STATUS_BLOCK iosb;
    NTSTATUS        status;

    devObj = IoGetRelatedDeviceObject(connectionFileObject);

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = TdiBuildInternalDeviceControlIrp(TDI_DISCONNECT, devObj, connectionFileObject, &event, &iosb);

    if (irp == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    TdiBuildDisconnect(irp, devObj, connectionFileObject, NULL, NULL, NULL, flags, NULL, NULL);

    status = IoCallDriver(devObj, irp);

    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
        status = iosb.Status;
    }

    return status;
}
Пример #2
0
NTSTATUS
	TdiDisconnect(
		PFILE_OBJECT ConnectionObject
		)
{
	NTSTATUS	ntStatus;
    KEVENT		Event; 
	PIRP		Irp;
    PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
    IO_STATUS_BLOCK IoStatus;

	KeInitializeEvent(&Event, NotificationEvent, FALSE);

    if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_DISCONNECT, DeviceObject, ConnectionObject, &Event, &IoStatus)))
		return STATUS_INSUFFICIENT_RESOURCES;

    TdiBuildDisconnect(Irp, DeviceObject, ConnectionObject, 0, 0, 0, TDI_DISCONNECT_RELEASE, 0, 0);

    ntStatus = IoCallDriver(DeviceObject, Irp);

    if (ntStatus == STATUS_PENDING)
        ntStatus = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0);

    return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus);

}
Пример #3
0
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;
}
Пример #4
0
NTSTATUS
LpxTdiDisconnect(
	IN	PFILE_OBJECT	ConnectionFileObject,
	IN	ULONG			Flags
	)
{
    PDEVICE_OBJECT	deviceObject;
	PIRP			irp;
	KEVENT			event;
	IO_STATUS_BLOCK	ioStatusBlock;
	NTSTATUS		ntStatus;

    LtDebugPrint (3, ("LpxTdiDisconnect:  Entered\n"));
	ASSERT(ConnectionFileObject);

	//
	// Make Event.
	//
	KeInitializeEvent(&event, NotificationEvent, FALSE);

    deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject);

	//
	// Make IRP.
	//
	irp = TdiBuildInternalDeviceControlIrp(
			TDI_DISCONNECT,
			deviceObject,
			ConnectionFileObject,
			&event,
			&ioStatusBlock
			);
	if(irp == NULL) {
		LtDebugPrint(1, ("[LpxTdi]KSTdiDisconnect: Can't Build IRP.\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	
	TdiBuildDisconnect(
		irp,
		deviceObject,
		ConnectionFileObject,
		NULL,
		NULL,
		NULL,
		Flags,
		NULL,
		NULL
		);

	irp->MdlAddress = NULL;

	ntStatus = LpxTdiIoCallDriver(
				deviceObject,
				irp,
				&ioStatusBlock,
				&event,
				NULL
				);

	if(!NT_SUCCESS(ntStatus)) {
		LtDebugPrint(1, ("[LpxTdi]LpxTdiDisconnect: Failed. ntStatus = %x\n", ntStatus));
	}

	return ntStatus;
}
Пример #5
0
void
ot_free(void)
{
	KIRQL irql;
	int i;
	struct ot_entry *ote;

	if (g_ot_hash == NULL)
		return;					// have nothing to do

	// do cleanup for address & connection objects
	for (i = 0; i < HASH_SIZE; i++) {

		for (;;) {			// do it again and again
			PFILE_OBJECT connobj = NULL, event_addrobj;
			PVOID event_handler = NULL, event_context;
			int event_type;
			PDEVICE_OBJECT devobj;

			KeAcquireSpinLock(&g_ot_hash_guard, &irql);

			for (ote = g_ot_hash[i]; ote != NULL; ote = ote->next) {

				if (ote->fileobj == NULL)
					continue;				// skip processed items

#ifdef _USE_TDI_HOOKING
				devobj = ote->devobj;
#else
				devobj = get_original_devobj(ote->devobj, NULL);
#endif

				if (ote->type == FILEOBJ_ADDROBJ) {
					// find at least one event handler & remove it @ PASSIVE level
					int j;
					
					event_addrobj = ote->fileobj;
					
					for (j = 0; j < MAX_EVENT; j++)
						if (ote->ctx[j].old_handler != NULL) {
	
							event_type = j;
							event_handler = ote->ctx[j].old_handler;
							event_context = ote->ctx[j].old_context;

							KdPrint(("[tdi_fw] ot_free: got event handler to restore (addrobj: 0x%x; type: %d; handler: 0x%x; context: 0x%x\n",
								event_addrobj,
								event_type,
								event_handler,
								event_context));

							ote->ctx[j].old_handler = NULL;

							break;
						}

					if (event_handler != NULL)
						break;

					KdPrint(("[tdi_fw] ot_free: no event handlers for addrobj: 0x%x\n",
						ote->fileobj));

					// remove this addrobj from "LISTEN" state
					if (ote->listen_entry != NULL) {
						del_listen_obj(ote->listen_entry, FALSE);
						ote->listen_entry = NULL;
					}

					// no event handlers
					ote->fileobj = NULL;

				} else if (ote->type == FILEOBJ_CONNOBJ) {
					// check connobj is connected (remote addr is not 0)
					TA_ADDRESS *remote_addr = (TA_ADDRESS *)(ote->remote_addr);

					if (((TDI_ADDRESS_IP *)(remote_addr->Address))->in_addr == 0) {
						KdPrint(("[tdi_fw] ot_free: connobj 0x%x is not connected\n", connobj));

					} else {
						// disconnect this connection using TDI_DISCONNECT @ PASSIVE level
						connobj = ote->fileobj;
						
						KdPrint(("[tdi_fw] ot_free: got connobj 0x%x (%x:%x) to disconnect\n",
							connobj,
							((TDI_ADDRESS_IP *)(remote_addr->Address))->in_addr,
							((TDI_ADDRESS_IP *)(remote_addr->Address))->sin_port));
					}

					// remove this connobj from "CONNECTED" state
					if (ote->conn_entry != NULL) {
						del_tcp_conn_obj(ote->conn_entry, FALSE);
						ote->conn_entry = NULL;

						// TODO: check if state TCP_STATE_TIME_WAIT don't delete it
					}

					// skip this object next time
					ote->fileobj = NULL;
				}
			}

			KeReleaseSpinLock(&g_ot_hash_guard, irql);

			// we're at PASSIVE level

			if (event_handler != NULL) {
				// set old event handler
				PIRP query_irp;
				NTSTATUS status;

				KdPrint(("[tdi_fw] ot_free: got event handler to restore (addrobj: 0x%x; type: %d; handler: 0x%x; context: 0x%x\n",
					event_addrobj,
					event_type,
					event_handler,
					event_context));

				query_irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER,
					devobj, event_addrobj, NULL, NULL);
				if (query_irp == NULL) {
					KdPrint(("[tdi_fw] ot_free: TdiBuildInternalDeviceControlIrp\n"));
					continue;
				}

				TdiBuildSetEventHandler(query_irp, devobj, event_addrobj, NULL, NULL,
					event_type,	event_handler, event_context);

				status = IoCallDriver(devobj, query_irp);
				if (status != STATUS_SUCCESS)
					KdPrint(("[tdi_fw] ot_free: IoCallDriver(set_event_handler): 0x%x\n", status));

			} else if (connobj != NULL) {
				// disconnect connection
				PIRP query_irp;
				NTSTATUS status;

				KdPrint(("[tdi_fw] ot_free: disconnecting connobj 0x%x\n", connobj));

				query_irp = TdiBuildInternalDeviceControlIrp(TDI_DISCONNECT,
					devobj, connobj, NULL, NULL);
				if (query_irp == NULL) {
					KdPrint(("[tdi_fw] ot_free: TdiBuildInternalDeviceControlIrp\n"));
					continue;
				}

				// using TDI_DISCONNECT_RELEASE to make ClientEventDisconnect to be called
				TdiBuildDisconnect(query_irp, devobj, connobj, NULL, NULL, NULL,
					TDI_DISCONNECT_RELEASE, NULL, NULL);

				status = IoCallDriver(devobj, query_irp);
				if (status != STATUS_SUCCESS)
					KdPrint(("[tdi_fw] ot_free: IoCallDriver(disconnect): 0x%x\n", status));

			} else {
				
				// no objects to process. break!
				
				break;
			}
		}
	}

	// clear it!
	KeAcquireSpinLock(&g_ot_hash_guard, &irql);

	for (i = 0; i < HASH_SIZE; i++) {
		struct ot_entry *ote = g_ot_hash[i];
		while (ote != NULL) {
			struct ot_entry *ote2 = ote->next;

			KdPrint(("[tdi_fw] ot_free: Warning! fileobj 0x%x type %d exists!\n",
				ote->fileobj, ote->type));
			
			if (ote->sid_a != NULL)
				free(ote->sid_a);
			free(ote);

			ote = ote2;
		}
	}
	free(g_ot_hash);
	g_ot_hash = NULL;
	
	KeReleaseSpinLock(&g_ot_hash_guard, irql);

	// and cleanup cte_hash
	if (g_cte_hash != NULL) {
		KeAcquireSpinLock(&g_cte_hash_guard, &irql);

		for (i = 0; i < HASH_SIZE; i++) {
			struct ctx_entry *cte = g_cte_hash[i];
			while (cte) {
				struct ctx_entry *cte2 = cte->next;
				free(cte);
				cte = cte2;
			}
		}
		free(g_cte_hash);
		g_cte_hash = NULL;

		KeReleaseSpinLock(&g_cte_hash_guard, irql);
	}
}
Пример #6
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;
}