Exemplo n.º 1
0
NTSTATUS tdi_set_event_handler(PFILE_OBJECT addressFileObject, LONG eventType, PVOID eventHandler, PVOID eventContext)
{
    PDEVICE_OBJECT  devObj;
    KEVENT          event;
    PIRP            irp;
    IO_STATUS_BLOCK iosb;
    NTSTATUS        status;

    devObj = IoGetRelatedDeviceObject(addressFileObject);

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, devObj, addressFileObject, &event, &iosb);

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

    TdiBuildSetEventHandler(irp, devObj, addressFileObject, NULL, NULL, eventType, eventHandler, eventContext);

    status = IoCallDriver(devObj, irp);

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

    return status;
}
Exemplo n.º 2
0
NTSTATUS
	TdiSetEventHandler(
		PFILE_OBJECT	AddressObject,
		LONG			EventType, 
		PVOID			EventHandler,
		PVOID			EventContext
		)
{
	NTSTATUS	ntStatus;
    KEVENT		Event; 
	PIRP		Irp;
    PDEVICE_OBJECT	DeviceObject = IoGetRelatedDeviceObject(AddressObject);
	IO_STATUS_BLOCK IoStatus;
    
	KeInitializeEvent(&Event, NotificationEvent, FALSE);

    if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, DeviceObject, AddressObject, &Event, &IoStatus)))
		return STATUS_INSUFFICIENT_RESOURCES;

    TdiBuildSetEventHandler(Irp, DeviceObject, AddressObject, 0, 0, EventType, EventHandler, EventContext);

    ntStatus = IoCallDriver(DeviceObject, Irp);

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

    return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus);
}
Exemplo n.º 3
0
NTSTATUS
TcpSetDisconnectHandler(
						IN	PFILE_OBJECT	AddressFileObject,
						IN	PVOID			InEventHandler,
						IN	PVOID			InEventContext
						)
{
	PDEVICE_OBJECT	deviceObject;
	PIRP			irp;
	KEVENT			event;
	IO_STATUS_BLOCK	ioStatusBlock;
	NTSTATUS		ntStatus;

    TCPLtDebugPrint (3, ("[TcpTdi]TcpSetDisconnectHandler:  Entered\n"));
	//
	// Make Event.
	//
	KeInitializeEvent(&event, NotificationEvent, FALSE);

    deviceObject = IoGetRelatedDeviceObject(AddressFileObject);

	//
	// Make IRP.
	//
	irp =  TdiBuildInternalDeviceControlIrp(
			TDI_SET_EVENT_HANDLER,
			deviceObject,
			AddressFileObject,
			&event,
			&ioStatusBlock
			);
	if(irp == NULL) {
		TCPLtDebugPrint(1, ("[TcpTdi]TcpSetDisconnectHandler: Can't Build IRP.\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	
	TdiBuildSetEventHandler(
		irp,
		deviceObject,
		AddressFileObject,
		NULL,
		NULL,
		TDI_EVENT_DISCONNECT,
		InEventHandler,
		InEventContext
		);

	ntStatus = TcpTdiIoCallDriver(
				deviceObject,
				irp,
				&ioStatusBlock,
				&event
				);

	if(!NT_SUCCESS(ntStatus)) {
		TCPLtDebugPrint(1, ("[TcpTdi]TcpSetDisconnectHandler: Failed.\n"));
	}

	return ntStatus;
}
Exemplo n.º 4
0
VOID DestroyNodeEventHandlerVisitor(PVOID context, UINT key, PVOID value)
{
	NTSTATUS status;
	PIRP irp = NULL;
	unsigned int i = 0;
	KEVENT irp_complete_event;
	IO_STATUS_BLOCK io_status_block;
	NodeEventHandler* node_event_handler = NULL;
	EventHandlerManager* event_handler_manager = NULL;

	node_event_handler = (NodeEventHandler*)value;
	event_handler_manager = (EventHandlerManager*)context;

	if(node_event_handler == NULL ||
		event_handler_manager == NULL )
		return;

	KeInitializeEvent(&irp_complete_event, NotificationEvent, FALSE);

	// For each hooked event handler send an IRP to set the event handler
	// back to what it originally was
	for(i = 0; i < TDI_EVENT_HANDLERS_MAX; i++)
	{
		PFILE_OBJECT node = node_event_handler->handlers[i].node;
		TdiEventHandler* original_handler = &node_event_handler->handlers[i].original_handler;

		if(original_handler->EventHandler == NULL)
			continue;

		irp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER, event_handler_manager->connection_manager->device, node, 
			&irp_complete_event, &io_status_block);

		if(irp == NULL)
			continue;

		TdiBuildSetEventHandler(irp, event_handler_manager->connection_manager->device, node, NULL, NULL, 
			original_handler->EventType, original_handler->EventHandler, original_handler->EventContext);

		status = IoCallDriver(event_handler_manager->connection_manager->next_device, irp);

		if(status == STATUS_PENDING)                                
		{
			// Wait for the IRP to finish
			KeWaitForSingleObject((PVOID)&irp_complete_event, Executive, KernelMode, TRUE, NULL); 
			status = io_status_block.Status; 
		}

		if(status == STATUS_SUCCESS)
		{
			DbgPrint("EventHandlerManager: Successfully set original event handler n=%08x t=%08x\n", node, original_handler->EventType);
		}
		else
		{
			DbgPrint("EventHandlerManager: Failed to set original event handler - code=%08x n=%08x t=%08x\n", status, node, original_handler->EventType);
		}

		KeResetEvent(&irp_complete_event);
	}
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
NTSTATUS
LpxTdiSetReceiveDatagramHandler(
		IN	PFILE_OBJECT	AddressFileObject,
		IN	PVOID			InEventHandler,
		IN	PVOID			InEventContext
	) {
	PDEVICE_OBJECT	deviceObject;
	PIRP			irp;
	KEVENT			event;
	IO_STATUS_BLOCK	ioStatusBlock;
	NTSTATUS		ntStatus;

    LtDebugPrint (1, ("[LxpTdi]LpxSetReceiveDatagramHandler:  Entered\n"));

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

    deviceObject = IoGetRelatedDeviceObject(AddressFileObject);

	//
	// Make IRP.
	//
	irp = TdiBuildInternalDeviceControlIrp(
			TDI_SET_EVENT_HANDLER,
			deviceObject,
			AddressFileObject,
			&event,
			&ioStatusBlock
			);
	if(irp == NULL) {
		LtDebugPrint(1, ("[LpxTdi]LpxSetReceiveDatagramHandler: Can't Build IRP.\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	
	TdiBuildSetEventHandler(
		irp,
		deviceObject,
		AddressFileObject,
		NULL,
		NULL,
		TDI_EVENT_RECEIVE_DATAGRAM,
		InEventHandler,
		InEventContext
		);

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

	if(!NT_SUCCESS(ntStatus)) {
		LtDebugPrint(1, ("[LpxTdi]LpxSetReceiveDatagramHandler: Can't Build IRP.\n"));
	}

	LtDebugPrint(3, ("[LpxTdi] Leave LpxSetReceiveDatagramHandler\n"));

	return ntStatus;
}
Exemplo n.º 7
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);
	}
}