Example #1
0
NTSTATUS
LpxTdiIoCallDriver(
    IN		PDEVICE_OBJECT		DeviceObject,
    IN OUT	PIRP				Irp,
	IN		PIO_STATUS_BLOCK	IoStatusBlock,
	IN		PKEVENT				Event,
	IN		PLARGE_INTEGER		TimeOut
    )
{
	NTSTATUS		ntStatus;
	NTSTATUS		wait_status;
//	LARGE_INTEGER	timeout;

	//
	//	set a expire time to IRP.
	//	LPX takes whole charge of IRP completion.
	//	LPX will measure time-out.
	//	Do not wait with time-out here.
	//	BSOD may occur if you do.
	//
	//	added by hootch 02092004
	if(TimeOut)
		SET_IRP_EXPTIME(Irp, CurrentTime().QuadPart + TimeOut->QuadPart);
	else
		SET_IRP_EXPTIME(Irp, 0);

	Irp->Tail.Overlay.DriverContext[2] = (PVOID)0;
	
	LtDebugPrint(2, ("[LpxTdi] Irp->Tail.Overlay.DriverContext[2] == %p\n", Irp->Tail.Overlay.DriverContext[2]));
	

	ntStatus = IoCallDriver(
				DeviceObject,
				Irp
				);

	if(ntStatus == STATUS_PENDING) {
		if(Event) {
		wait_status = KeWaitForSingleObject(
					Event,
					Executive,
					KernelMode,
					FALSE,
					NULL
					);

		if(wait_status != STATUS_SUCCESS) {
			LtDebugPrint(1, ("[LpxTdi] LpxTdiIoCallDriver: Wait for event Failed.\n"));
			return STATUS_CONNECTION_DISCONNECTED; // STATUS_TIMEOUT;
		}
		} else {
			return ntStatus;
		}
	}

    ntStatus = IoStatusBlock->Status;

	return ntStatus;
}
Example #2
0
NTSTATUS
LpxTdiRecvWithCompletionEvent_TimeOut(
	IN	PFILE_OBJECT			ConnectionFileObject,
	IN  PTDI_RECEIVE_CONTEXT	TdiReceiveContext,
	OUT	PUCHAR					RecvBuffer,
	IN	ULONG					RecvLength,
	IN	ULONG					Flags,
	IN	PLARGE_INTEGER			TimeOut
	)
{
    PDEVICE_OBJECT			deviceObject;
	PIRP					irp;
	NTSTATUS				ntStatus;
	PMDL					mdl;


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

	if((RecvBuffer == NULL) || (RecvLength == 0))
	{
		LtDebugPrint(1, ("[LpxTdi]TdiReceive: Rcv buffer == NULL or RcvLen == 0.\n"));
		return STATUS_NOT_IMPLEMENTED;
	}

 	
    deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject);

	//
	// Make IRP.
	//
	irp = TdiBuildInternalDeviceControlIrp(
			TDI_RECEIVE,
			deviceObject,
			connectionFileObject,
			NULL,
			NULL
			);
	
	if(irp == NULL) 
	{
		LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Build IRP.\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	mdl = IoAllocateMdl(
				RecvBuffer,
				RecvLength,
				FALSE,
				FALSE,
				irp
				);
	if(mdl == NULL) 
	{
		LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Allocate MDL.\n"));
		IoFreeIrp(irp);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	mdl->Next = NULL;
	MmBuildMdlForNonPagedPool(mdl);
	
	TdiBuildReceive(
		irp,
		deviceObject,
		ConnectionFileObject,
		LpxTdiRecvWithCompletionEventCompletionRoutine,
		TdiReceiveContext,
		mdl,
		Flags,
		RecvLength
		);
	

	if(TimeOut) 
		SET_IRP_EXPTIME(irp, CurrentTime().QuadPart + TimeOut->QuadPart);
	else
		SET_IRP_EXPTIME(irp, 0);

	ntStatus = IoCallDriver(
				deviceObject,
				irp
				);

	if(!NT_SUCCESS(ntStatus)) 
	{
		TdiReceiveContext->Irp = NULL;
		LtDebugPrint(1, ("[LpxTdi]LpxTdiRecv: Failed.\n"));
	
		return ntStatus;
	}

	TdiReceiveContext->Irp = irp;
	
	return ntStatus;
}
Example #3
0
NTSTATUS
LpxTdiIoCallDriver(
	IN PDEVICE_OBJECT	DeviceObject,
	IN PIRP				Irp,
	OUT PTRANS_STAT		TransStat,
	IN PLARGE_INTEGER	TimeOut,
	IN BOOLEAN			Synchronous
){
	NTSTATUS			ntStatus;
	PKEVENT				userEvent;
	PIO_STATUS_BLOCK	userIoStatusBlock;

	//
	//	set a expire time to IRP.
	//	LPX takes whole charge of IRP completion.
	//	LPX will measure time-out.
	//	Do not wait with time-out here to prevent BSOD.
	//
	if(TimeOut)
		SET_IRP_EXPTIME(Irp, CurrentTime().QuadPart + TimeOut->QuadPart);
	else
		SET_IRP_EXPTIME(Irp, 0);

	Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_FOR_TRANS_STAT] = (PVOID)TransStat; // This entry is used for getting flow control hint.

	LtDebugPrint(2, ("[LpxTdi] LpxTdiIoCallDriver: Irp->Tail.Overlay.DriverContext[2] == %p\n",
		Irp->Tail.Overlay.DriverContext[DRIVER_CONTEXT_FOR_TRANS_STAT]));


	//
	//	Extract event and IoStatusBlock set by the caller
	//

	if(Synchronous) {
		userEvent = Irp->UserEvent;
		userIoStatusBlock = Irp->UserIosb;
		if(userIoStatusBlock == NULL) {
			return STATUS_INVALID_PARAMETER;
		}
		if(Synchronous && userEvent == NULL) {
			return STATUS_INVALID_PARAMETER;
		}
	} else {
		userEvent = NULL;
		userIoStatusBlock = NULL;
	}


	//
	//	Send IRP to the target device object.
	//

	ntStatus = IoCallDriver(
				DeviceObject,
				Irp
				);
	if(ntStatus == STATUS_PENDING) {
		NTSTATUS			wait_status;

		//
		//	Target device is doing the request asynchronously.
		//	If user event is set, wait for it instead of the caller.
		//

		if(Synchronous) {
			wait_status = KeWaitForSingleObject(
					userEvent,
					Executive,
					KernelMode,
					FALSE,
					NULL
					);

			if(wait_status == STATUS_SUCCESS) {
				return userIoStatusBlock->Status;
			} else {
				LtDebugPrint(1, ("[LpxTdi] LpxTdiIoCallDriver: Wait for event Failed.\n"));
				ASSERT(FALSE);
				return STATUS_CONNECTION_DISCONNECTED;
			}
		}

	} else {


		//
		//	the IRP is completed synchronously
		//

		//
		//	If return value from IoCallDriver() is SUCCESS,
		//	Make IoStatusBlock and return value same 
		//  by returning userIoStatusBlock.
		//	If not, forwards the return value.
		//

		if (ntStatus == STATUS_SUCCESS) {
			if(userIoStatusBlock) {
				ASSERT(userIoStatusBlock->Status != STATUS_PENDING);
				return userIoStatusBlock->Status;
			}
		} else {
			if(userIoStatusBlock) {
				userIoStatusBlock->Status = ntStatus;
			}
		}
	}

	return ntStatus;
}