I see a part of codes as following
VOID
usbsnifferProcessInternalDeviceControl(
IN WDFDEVICE Device,
IN Pusbsniffer_CONTEXT Context,
IN WDFREQUEST Request,
IN ULONG IoControlCode,
IN BOOLEAN bCompletion,
OUT BOOLEAN* bRead
)
{
*bRead = FALSE;
if (usbsnifferFiltering && Context->FilterEnabled)
{
if (bCompletion)
{
usbsnifferPrint(usbsniffer_DEBUG_INFO, "usbsnifferIoInternalDeviceControlComplete - Id: %d, IOCTL: %d\n", Context->DeviceId, IoControlCode);
}
else
{
usbsnifferPrint(usbsniffer_DEBUG_INFO, "usbsnifferIoInternalDeviceControl - Id: %d, IOCTL: %d\n", Context->DeviceId, IoControlCode);
}
switch (IoControlCode)
{
case IOCTL_INTERNAL_USB_SUBMIT_URB:
{
PURB pUrb;
usbsnifferPrint(usbsniffer_DEBUG_INFO, " IOCTL_INTERNAL_USB_SUBMIT_URB\n");
pUrb = (PURB) IoGetCurrentIrpStackLocation(WdfRequestWdmGetIrp(Request))->Parameters.Others.Argument1;
//
// Figure out what kinda urb we have and set up transfer vars
//
switch (pUrb->UrbHeader.Function)
{
case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
{
struct _URB_BULK_OR_INTERRUPT_TRANSFER* pTransfer = (struct _URB_BULK_OR_INTERRUPT_TRANSFER*)pUrb;
*bRead = (BOOLEAN)(pTransfer->TransferFlags & USBD_TRANSFER_DIRECTION_IN);
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER\n");
__usbsnifferProcessUrbTransfer(
Device,
Context,
pUrb,
pTransfer->TransferBuffer,
pTransfer->TransferBufferMDL,
pTransfer->TransferBufferLength,
bCompletion,
*bRead);
break;
}
case URB_FUNCTION_CONTROL_TRANSFER:
{
struct _URB_CONTROL_TRANSFER* pTransfer = (struct _URB_CONTROL_TRANSFER*)pUrb;
*bRead = (BOOLEAN)(pTransfer->TransferFlags & USBD_TRANSFER_DIRECTION_IN);
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_CONTROL_TRANSFER\n");
__usbsnifferProcessUrbTransfer(
Device,
Context,
pUrb,
pTransfer->TransferBuffer,
pTransfer->TransferBufferMDL,
pTransfer->TransferBufferLength,
bCompletion,
*bRead);
break;
}
case URB_FUNCTION_VENDOR_DEVICE:
case URB_FUNCTION_VENDOR_INTERFACE:
case URB_FUNCTION_VENDOR_ENDPOINT:
case URB_FUNCTION_VENDOR_OTHER:
case URB_FUNCTION_CLASS_DEVICE:
case URB_FUNCTION_CLASS_INTERFACE:
case URB_FUNCTION_CLASS_ENDPOINT:
case URB_FUNCTION_CLASS_OTHER:
{
struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST* pTransfer = (struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST*)pUrb;
*bRead = (BOOLEAN)(pTransfer->TransferFlags & USBD_TRANSFER_DIRECTION_IN);
switch (pUrb->UrbHeader.Function)
{
case URB_FUNCTION_VENDOR_DEVICE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_VENDOR_DEVICE\n");
break;
case URB_FUNCTION_VENDOR_INTERFACE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_VENDOR_INTERFACE\n");
break;
case URB_FUNCTION_VENDOR_ENDPOINT:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_VENDOR_ENDPOINT\n");
break;
case URB_FUNCTION_VENDOR_OTHER:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_VENDOR_OTHER\n");
break;
case URB_FUNCTION_CLASS_DEVICE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_CLASS_DEVICE\n");
break;
case URB_FUNCTION_CLASS_INTERFACE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_CLASS_INTERFACE\n");
break;
case URB_FUNCTION_CLASS_ENDPOINT:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_CLASS_ENDPOINT\n");
break;
case URB_FUNCTION_CLASS_OTHER:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_CLASS_OTHER\n");
break;
}
__usbsnifferProcessUrbTransfer(
Device,
Context,
pUrb,
pTransfer->TransferBuffer,
pTransfer->TransferBufferMDL,
pTransfer->TransferBufferLength,
bCompletion,
*bRead);
break;
}
case URB_FUNCTION_ISOCH_TRANSFER:
{
struct _URB_ISOCH_TRANSFER* pTransfer = (struct _URB_ISOCH_TRANSFER*)pUrb;
*bRead = (BOOLEAN)(pTransfer->TransferFlags & USBD_TRANSFER_DIRECTION_IN);
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_ISOCH_TRANSFER\n");
__usbsnifferProcessUrbTransfer(
Device,
Context,
pUrb,
pTransfer->TransferBuffer,
pTransfer->TransferBufferMDL,
pTransfer->TransferBufferLength,
bCompletion,
*bRead);
break;
}
case URB_FUNCTION_ABORT_PIPE:
case URB_FUNCTION_RESET_PIPE:
case URB_FUNCTION_SYNC_RESET_PIPE:
case URB_FUNCTION_SYNC_CLEAR_STALL:
{
usbsniffer_REQUEST_PARAMS params;
usbsniffer_REQUEST_PARAMS_INIT(¶ms);
switch (pUrb->UrbHeader.Function)
{
case URB_FUNCTION_ABORT_PIPE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_ABORT_PIPE\n");
break;
case URB_FUNCTION_RESET_PIPE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_RESET_PIPE\n");
break;
case URB_FUNCTION_SYNC_RESET_PIPE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_SYNC_RESET_PIPE\n");
break;
case URB_FUNCTION_SYNC_CLEAR_STALL:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_SYNC_CLEAR_STALL\n");
break;
}
params.p1 = usbsnifferUSBSubmitURB;
params.p3 = pUrb->UrbHeader.Function;
usbsnifferAddTraceToFifo(Device,
Context->DeviceId,
usbsnifferInternalDeviceControlRequest,
params,
NULL,
0);
break;
}
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT:
case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE:
case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT:
case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE:
{
switch (pUrb->UrbHeader.Function)
{
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n");
*bRead = TRUE;
break;
case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT\n");
*bRead = TRUE;
break;
case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n");
*bRead = TRUE;
break;
case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE\n");
break;
case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT\n");
break;
case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE\n");
break;
}
__usbsnifferProcessUrbDescriptorRequest(
Device,
Context,
pUrb,
bCompletion,
*bRead);
break;
}
default:
usbsnifferPrint(usbsniffer_DEBUG_INFO, " URB_FUNCTION: %d\n", pUrb->UrbHeader.Function);
break;
}
break;
}
}
}
in the switch pUrb->UrbHeader.Function is the case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER means it can send the meesage?
if there any book can help me to distinguish these connection, thanks a lot.