📄 usbfx2lk_usb.cpp
字号:
// and submit to the device
// Urb - Address of the USB to be delivered.
//
// OUTPUTS:
//
// None
//
// RETURNS:
//
// None
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL
//
// CONTEXT:
//
// Arbitrary Context
//
// NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SubmitIrpAndUrbAsync(PUSBFX2LK_EXT DevExt, PIRP Irp, PURB Urb)
{
PIO_STACK_LOCATION nextStack;
NTSTATUS status;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,
("SubmitIrpAndUrbAsync: Enter\n"));
//
// We need to submit this request as a USB request,
// so we'll get the next IRP stack location and set
// it up as a USB interrupt transfer.
//
nextStack = IoGetNextIrpStackLocation(Irp);
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
nextStack->Parameters.Others.Argument1 = Urb;
//
// Setup our completion routine that will free the URB
//
IoSetCompletionRoutine(Irp, AsynchronousUrbRequestCompletion,
Urb, TRUE, TRUE, TRUE);
//
// We're submitting this URB to the device and it may
// complete at an arbitrary point in the future, so
// we need to mark it pending
//
IoMarkIrpPending(Irp);
//
// While we have the Irp in our queue, store the address of the URB
// in the DriverContext[1] field of the Irp. We do this so that
// if the Irp is canceled while in our queue, we have enough information
// to do the correct cleanup.
//
Irp->Tail.Overlay.DriverContext[1] = Urb;
//
// Queue the using the appropriate cancel safe queue routin
//
#ifdef W2K3
//
// IoCsqInsertIrpEx returns whatever we return from OsrCsqInsertIoIrpEx,
// which for us is STATUS_SUCCESS.
//
status = IoCsqInsertIrpEx(&DevExt->CancelSafeIoQueue,Irp,NULL,DevExt);
ASSERT(status == STATUS_SUCCESS);
#else // W2K3
IoCsqInsertIrp(&DevExt->CancelSafeIoQueue,Irp,NULL);
#endif // W2K3
//
// We have queued this IRP onto our internal queue.
// Now call our helper routine ProcessNextIrpInQueue
// to pass this request (or possibly another request
// that was running parallel and beat us to the queue)
// to the host controller.
//
// ProcessNextIrpInQueue will pass the request on to the
// host if we are in an applicable PnP state otherwise the
// request will just stay in the queue.
//
ProcessNextIrpInQueue(DevExt);
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,
("SubmitIrpAndUrbAsync: Exit\n"));
return STATUS_PENDING;
}
///////////////////////////////////////////////////////////////////////////////
//
// SubmitResetPipe
//
// Resets the passed in pipe
//
// INPUTS:
//
// DevExt - One of our device extensions
//
// Irp - Pointer to an IOCTL_OSRUSBFX2_RESET_PIPE
// IRP.
//
// Pipe - The USBFX2_PIPE_ENUM for the pipe to reset
//
// OUTPUTS:
//
// None
//
// RETURNS:
//
// An appropriate NTSTATUS value
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL
//
// CONTEXT:
//
// User context
//
// NOTES:
//
// Routine assumes that the output data buffer in the IRP is
// valid for this request. Must be checked by caller.
//
// Called relinquishes ownership of the IRP when calling this
// routine, IRP must NOT be touched by caller after this routine
// returns
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SubmitResetPipe(PUSBFX2LK_EXT DevExt, PIRP Irp, USBFX2_PIPE_ENUM Pipe)
{
NTSTATUS status;
PURB resetUrb;
PUSBFX2LK_PIPE_CONTEXT pipeContext = NULL;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("ResetPipe: Enter\n"));
//
// Find the pipe context for the pipe that we're resetting
//
switch(Pipe) {
case USBFx2BulkInPipe:
pipeContext = DevExt->BulkInPipe;
break;
case USBFx2BulkOutPipe:
pipeContext = DevExt->BulkOutPipe;
break;
case USBFx2InterruptPipe:
pipeContext = DevExt->InterruptPipe;
break;
default:
//
// Bogus pipe
//
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,("ResetPipe: Exit Invalid Pipe\n"));
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER;
}
//
// We'd better have a pipe at this point,
// otherwise our device configuration failed
//
ASSERT(pipeContext);
//
// Allocate our reset URB
//
resetUrb =
(PURB)ExAllocatePoolWithTag(NonPagedPool,
sizeof(struct _URB_PIPE_REQUEST),
'PRxF');
if (!resetUrb) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
("ResetPipe: Failed to allocate memory, Exiting.\n"));
//
// We need to complete the IRP ourselves
//
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Setup the URB_FUNCTION_RESET_PIPE URB appropriately
//
resetUrb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST);
resetUrb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
resetUrb->UrbPipeRequest.PipeHandle = pipeContext->PipeInformation.PipeHandle;
status = SubmitIrpAndUrbAsync(DevExt, Irp, resetUrb);
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("ResetPipe: Exit\n"));
//
// Return whatever status SubmitIrpAndUrbAsync returned
//
return status;
}
///////////////////////////////////////////////////////////////////////////////
//
// SubmitGetBarGraphState
//
// This routine gets the state of the bar graph on the board
//
//
// INPUTS:
//
// DevExt - One of our device extensions
//
// Irp - Pointer to an IOCTL_OSRUSBFX2_GET_BAR_GRAPH_DISPLAY
// IRP. User's buffer has already been validated
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// An appropriate NTSTATUS value
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL
//
// CONTEXT:
//
// User context
//
// NOTES:
//
// Routine assumes that the output data buffer in the IRP is
// valid for this request. Must be checked by caller.
//
// Called relinquishes ownership of the IRP when calling this
// routine, IRP must NOT be touched by caller after this routine
// returns
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SubmitGetBarGraphState(PUSBFX2LK_EXT DevExt, PIRP Irp)
{
NTSTATUS status;
PURB getBarGraphUrb;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("GetBarGraphState: Enter\n"));
//
// Allocate our get bar graph URB
//
getBarGraphUrb =
(PURB)ExAllocatePoolWithTag(NonPagedPool,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
'BGxF');
if (!getBarGraphUrb) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
("GetBarGraphState: Failed to allocate memory, Exiting.\n"));
//
// We need to complete the IRP ourselves
//
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(getBarGraphUrb,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
//
// Build the vendor request with the appropriate
// flags and command
//
// We're getting data from the device,
// to we need to set the USBD_TRANSFER_DIRECTION_IN flag
//
UsbBuildVendorRequest(getBarGraphUrb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_SHORT_TRANSFER_OK | USBD_TRANSFER_DIRECTION_IN,
0,
USBFX2LK_READ_BARGRAPH_DISPLAY,
0,
0,
Irp->AssociatedIrp.SystemBuffer,
NULL,
sizeof(BAR_GRAPH_STATE),
NULL);
status = SubmitIrpAndUrbAsync(DevExt, Irp, getBarGraphUrb);
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("GetBarGraphState: Exit\n"));
//
// Return whatever status SubmitIrpAndUrbAsync returned
//
return status;
}
///////////////////////////////////////////////////////////////////////////////
//
// SubmitSetBarGraphState
//
// This routine sets the state of the bar graph on the board
//
//
// INPUTS:
//
// DevExt - One of our device extensions
//
// Irp - Pointer to an IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY
// IRP. User's buffer has already been validated
//
// OUTPUTS:
//
// None.
//
// RETURNS:
//
// An appropriate NTSTATUS value
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL
//
// CONTEXT:
//
// User context
//
// NOTES:
//
// Routine assumes that the output data buffer in the IRP is
// valid for this request. Must be checked by caller.
//
// Called relinquishes ownership of the IRP when calling this
// routine, IRP must NOT be touched by caller after this routine
// returns
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS SubmitSetBarGraphState(PUSBFX2LK_EXT DevExt, PIRP Irp)
{
NTSTATUS status;
PURB setBarGraphUrb;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_USB,("SetBarGraphState: Enter\n"));
//
// Allocate our set bar graph URB
//
setBarGraphUrb =
(PURB)ExAllocatePoolWithTag(NonPagedPool,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
'BSxF');
if (!setBarGraphUrb) {
OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_USB,
("SetBarGraphState: Failed to allocate memory, Exiting.\n"));
//
// We need to complete the IRP ourselves
//
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(setBarGraphUrb,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
//
// Build the vendor request with the appropriate
// flags and command
//
// We're getting data from the device,
// to we need to set the USBD_TRANSFER_DIRECTION_IN flag
//
UsbBuildVendorRequest(setBarGraphUrb,
URB_FUNCTION_VENDOR_DEVICE,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_SHORT_TRANSFER_OK,
0,
USBFX2LK_SET_BARGRAPH_DISPLAY,
0,
0,
Irp->AssociatedIrp.SystemBuffer,
NULL,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -