Exemplo n.º 1
0
VOID
UsbSamp_EvtReadWriteWorkItem(
    _In_ WDFWORKITEM  WorkItem
    )
{
    PWORKITEM_CONTEXT pItemContext;
    NTSTATUS status;

    UsbSamp_DbgPrint(3, ("ReadWriteWorkItem called\n"));

    pItemContext = GetWorkItemContext(WorkItem);

    status = ResetPipe(pItemContext->Pipe);
    if (!NT_SUCCESS(status)) {

        UsbSamp_DbgPrint(1, ("ResetPipe failed 0x%x\n", status));

        status = ResetDevice(pItemContext->Device);
        if (!NT_SUCCESS(status)){

            UsbSamp_DbgPrint(1, ("ResetDevice failed 0x%x\n", status));
        }
    }

    WdfObjectDelete(WorkItem);

    return;
}
Exemplo n.º 2
0
//
// Reset All Pipes
//
BOOL
BOT_ResetAllPipes(
    PUSBMSC_DEVICE pUsbDevice
    )
{
   BOOL bRc = FALSE;
   DWORD dwErr;

   INIT_DT;

   DEBUGMSG(ZONE_TRACE,(TEXT("USBMSC>BOT_ResetAllPipes\n")));

   START_DT

   // 0. reset endpoint 0
   dwErr = ResetDefaultEndpoint(pUsbDevice->UsbFuncs, 
                                pUsbDevice->hUsbDevice);

   if ( ERROR_SUCCESS == dwErr ) 
   {
        // 1. reset BulkIn endpoint
        if ( ResetPipe(pUsbDevice->UsbFuncs,
                       pUsbDevice->BulkIn.hPipe,
                       USB_NO_WAIT) ) 
        {
            // 2. reset BulkOut endpoint
            if ( ResetPipe(pUsbDevice->UsbFuncs,
                           pUsbDevice->BulkOut.hPipe,
                           USB_NO_WAIT) ) 
            {               
                bRc = TRUE;
            }
        }
    }

    BOT_ResetEvent(pUsbDevice->hEP0Event);
    BOT_ResetEvent(pUsbDevice->BulkIn.hEvent);
    BOT_ResetEvent(pUsbDevice->BulkOut.hEvent);

    STOP_DT( TEXT("BOT_ResetAllPipes"), 10, pUsbDevice->Timeouts.Reset );  

    DEBUGMSG(ZONE_TRACE,(TEXT("USBMSC<BOT_ResetAllPipes:%d\n"), bRc));
   
    return bRc;
}
Exemplo n.º 3
0
/*++
Routine Description:

This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
requests from the system.

Arguments:

Queue - Handle to the framework queue object that is associated
with the I/O request.
Request - Handle to a framework request object.

OutputBufferLength - length of the request's output buffer,
if an output buffer is available.
InputBufferLength - length of the request's input buffer,
if an input buffer is available.

IoControlCode - the driver-defined or system-defined I/O control code
(IOCTL) that is associated with the request.
Return Value:

VOID
--*/
VOID PSDrv_EvtIoDeviceControl(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode)
{
    WDFDEVICE					 device;
    PVOID						 ioBuffer;
    size_t						 bufLength;
    NTSTATUS					 status;
    PDEVICE_CONTEXT				 pDevContext;
    PFILE_CONTEXT				 pFileContext;
    ULONG						 length = 0;
	PSUSBDRV_PIPE_PROPERTY*		 pPipeProp;
	PSUSBDRV_CONTROL_TRANSFER*	 pControlTransfer;
	PSUSBDRV_DRIVER_VERSION*	 pDriverVersion;
	PSUSBDRV_INTERFACE_PROPERTY* pInterfaceProperty;
	unsigned int*				 pnDeviceSpeed;
	WDFMEMORY					 WdfMem = NULL; 
	PUCHAR                       pControlBuffer;
	WDFMEMORY					 WdfMemOut = NULL;

	
	WDF_USB_INTERFACE_SELECT_SETTING_PARAMS  selectSettingParams;

    UNREFERENCED_PARAMETER(InputBufferLength);

    PSDrv_DbgPrint(3, ("PSDrv_EvtIoDeviceControl - begins\n"));

    PAGED_CODE();

    // initialize variables
    device = WdfIoQueueGetDevice(Queue);
    pDevContext = GetDeviceContext(device);

    switch(IoControlCode)
	{
		case IOCTL_PSDRV_RESET_PIPE:
			PSDrv_DbgPrint(3, ("IOControl: ResetPipe\n"));

			pFileContext = GetFileContext(WdfRequestGetFileObject(Request));

			if (pFileContext->Pipe == NULL)
			{
				PSDrv_DbgPrint(3, ("Invalid pipe!\n"));
				status = STATUS_INVALID_PARAMETER;
			}
			else
			{
				status = ResetPipe(pFileContext->Pipe);
			}

			break;

		case IOCTL_PSDRV_ABORT_PIPE:
			PSDrv_DbgPrint(3, ("IOControl: AbortPipe\n"));

			pFileContext = GetFileContext(WdfRequestGetFileObject(Request));

			if (pFileContext->Pipe == NULL)
			{
				PSDrv_DbgPrint(3, ("Invalid pipe!\n"));
				status = STATUS_INVALID_PARAMETER;
			}
			else
			{
				status = AbortPipe(pFileContext->Pipe);
			}

			break;

		case IOCTL_PSDRV_GET_CONFIG_DESCRIPTOR:
			PSDrv_DbgPrint(3, ("IOControl: GetConfigDescriptor\n"));

			if (pDevContext->UsbConfigurationDescriptor)
			{
				length = pDevContext->UsbConfigurationDescriptor->wTotalLength;

				status = WdfRequestRetrieveOutputBuffer(Request, length, &ioBuffer, &bufLength);
				if(!NT_SUCCESS(status))
				{
					PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status));
					status = STATUS_INVALID_PARAMETER;
					break;
				}

				RtlCopyMemory(ioBuffer, pDevContext->UsbConfigurationDescriptor, length);

				status = STATUS_SUCCESS;
			}
			else
			{
				PSDrv_DbgPrint(3, ("UsbConfigurationDescriptor is NULL!\n"));
				status = STATUS_INVALID_DEVICE_STATE;
			}

			break;

		case IOCTL_PSDRV_RESET_DEVICE:
			PSDrv_DbgPrint(3, ("IOControl: ResetDevice\n"));

			status = ResetDevice(device);

			break;

		case IOCTL_PSDRV_CONTROL_TRANSFER:
			PSDrv_DbgPrint(3, ("IOControl: ControlTransfer\n"));

			//Get a pointer to the input buffer
			status = WdfRequestRetrieveInputMemory(Request, &WdfMem);
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputMemory failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			if (WdfMem == NULL)
			{
				PSDrv_DbgPrint(1, ("WdfMem is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pControlTransfer = WdfMemoryGetBuffer(WdfMem, NULL);
			if (pControlTransfer == NULL)
			{
				PSDrv_DbgPrint(1, ("pControlTransfer is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			//Get a pointer to the output buffer
			if (OutputBufferLength != 0)
			{
				status = WdfRequestRetrieveOutputMemory(Request, &WdfMemOut);
				if(!NT_SUCCESS(status))
				{
					PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputMemory failed! (Status = %x)\n", status));
					status = STATUS_INVALID_PARAMETER;
					break;
				}

				if (WdfMemOut == NULL)
				{
					PSDrv_DbgPrint(1, ("WdfMemOut is NULL!\n"));
					status = STATUS_INVALID_PARAMETER;
					break;
				}

				pControlBuffer = WdfMemoryGetBuffer(WdfMemOut, NULL);
				if (pControlBuffer == NULL)
				{
					PSDrv_DbgPrint(1, ("pControlBuffer is NULL!\n"));
					status = STATUS_INVALID_PARAMETER;
					break;
				}
			}
			else
			{
				PSDrv_DbgPrint(1, ("This control request has no buffer...\n"));
				pControlBuffer = NULL;
			}

			// Call the control transfer function
			status = ControlTransfer(pDevContext, pControlTransfer, pControlBuffer, OutputBufferLength, &length);

			break;

		case IOCTL_PSDRV_SET_PIPE_PROPERTY:
			PSDrv_DbgPrint(3, ("IOControl: SetPipeProperty\n"));

			status = WdfRequestRetrieveInputMemory(Request, &WdfMem); 
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputMemory failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			if (WdfMem == NULL)
			{
				PSDrv_DbgPrint(1, ("WdfMem is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pPipeProp = WdfMemoryGetBuffer(WdfMem, NULL);
			if (pPipeProp == NULL)
			{
				PSDrv_DbgPrint(1, ("pPipeProp is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pFileContext = GetFileContext(WdfRequestGetFileObject(Request));
			if (pFileContext->Pipe == NULL)
			{
				PSDrv_DbgPrint(3, ("Invalid pipe!\n"));
				status = STATUS_INVALID_PARAMETER;
			}
			else
			{
				status = SetPipeProperty(pFileContext, pPipeProp);
			}

			break;

		case IOCTL_PSDRV_SET_INTERFACE:
			PSDrv_DbgPrint(3, ("IOControl: SetInterface\n"));

			status = WdfRequestRetrieveInputMemory(Request, &WdfMem); 
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputMemory failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			if (WdfMem == NULL)
			{
				PSDrv_DbgPrint(1, ("WdfMem is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pInterfaceProperty = WdfMemoryGetBuffer(WdfMem, NULL);
			if (pInterfaceProperty == NULL)
			{
				PSDrv_DbgPrint(1, ("pInterfaceProperty is NULL!\n"));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			PSDrv_DbgPrint(3, ("SetInterface: Going to change AltIF to %d...\n", pInterfaceProperty->nAltIF));

			WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING(&selectSettingParams, pInterfaceProperty->nAltIF);

			status = WdfUsbInterfaceSelectSetting(pDevContext->UsbInterface, WDF_NO_OBJECT_ATTRIBUTES, &selectSettingParams);

			if (status == STATUS_SUCCESS)
			{
				pDevContext->nCurrIf = 0;
				pDevContext->nCurrAltIf = pInterfaceProperty->nAltIF;

				PSDrv_DbgPrint(3, ("SetInterface: AltIF is now %d...\n", pInterfaceProperty->nAltIF));
			}

			break;

		case IOCTL_PSDRV_GET_INTERFACE:
			PSDrv_DbgPrint(3, ("IOControl: GetInterface\n"));

			length = sizeof(PSUSBDRV_INTERFACE_PROPERTY);

			status = WdfRequestRetrieveOutputBuffer(Request, length, &pInterfaceProperty, &bufLength);
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pInterfaceProperty->nIF = pDevContext->nCurrIf;
			pInterfaceProperty->nAltIF = pDevContext->nCurrAltIf;

			status = STATUS_SUCCESS;

			break;

		case IOCTL_PSDRV_GET_DRIVER_VERSION:
			PSDrv_DbgPrint(3, ("IOControl: GetDriverVersion\n"));

			length = sizeof(PSUSBDRV_DRIVER_VERSION);

			status = WdfRequestRetrieveOutputBuffer(Request, length, &pDriverVersion, &bufLength);
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			pDriverVersion->nMajor = PSUSBDRV_MAJOR_VERSION;
			pDriverVersion->nMinor = PSUSBDRV_MINOR_VERSION;
			pDriverVersion->nMaintenance = PSUSBDRV_MAINTENANCE_VERSION;
			pDriverVersion->nBuild = PSUSBDRV_BUILD_VERSION;
			
			status = STATUS_SUCCESS;

			break;

		case IOCTL_PSDRV_GET_DEVICE_SPEED:
			PSDrv_DbgPrint(3, ("IOControl: GetDeviceSpeed\n"));

			length = sizeof(unsigned int);

			status = WdfRequestRetrieveOutputBuffer(Request, length, &pnDeviceSpeed, &bufLength);
			if(!NT_SUCCESS(status))
			{
				PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status));
				status = STATUS_INVALID_PARAMETER;
				break;
			}

			if (pDevContext->IsDeviceHighSpeed == TRUE)
			{
				*pnDeviceSpeed = PSUSBDRV_DEVICE_HIGH_SPEED;
			}
			else
			{
				*pnDeviceSpeed = PSUSBDRV_DEVICE_FULL_SPEED;
			}

			break;

		default:
			PSDrv_DbgPrint(3, ("Unknown IOControl! (ControlCode = %x)\n", IoControlCode));

			status = STATUS_INVALID_DEVICE_REQUEST;

			break;
    }

    WdfRequestCompleteWithInformation(Request, status, length);

	PSDrv_DbgPrint(3, ("PSDrv_EvtIoDeviceControl - ends\n"));

    return;
}
Exemplo n.º 4
0
VOID
Rio500_EvtIoDeviceControl(
  _In_ WDFQUEUE   Queue,
  _In_ WDFREQUEST Request,
  _In_ size_t     OutputBufferLength,
  _In_ size_t     InputBufferLength,
  _In_ ULONG      IoControlCode
)
/*++

Routine Description:

    This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
    requests from the system.

Arguments:

    Queue - Handle to the framework queue object that is associated
            with the I/O request.
    Request - Handle to a framework request object.

    OutputBufferLength - length of the request's output buffer,
                        if an output buffer is available.
    InputBufferLength - length of the request's input buffer,
                        if an input buffer is available.

    IoControlCode - the driver-defined or system-defined I/O control code
                    (IOCTL) that is associated with the request.
Return Value:

    VOID

--*/
{
  WDFDEVICE             device;
  PVOID                 ioBuffer;
  PRIO_IOCTL_BLOCK      ioBufferRio;
  size_t                bufLength;
  NTSTATUS              status;
  PDEVICE_CONTEXT       pDevContext;
  ULONG                 length = 0;
  URB                   urb;
  PMDL                  pMdl = NULL;
  WDF_MEMORY_DESCRIPTOR memoryDesc;
#ifdef _WIN64
  BOOLEAN               isWowRequest = FALSE;
#endif // _WIN64

  UNREFERENCED_PARAMETER(OutputBufferLength);
  UNREFERENCED_PARAMETER(InputBufferLength);

  Rio500_DbgPrint(3, ("Entered Rio500_DispatchDevCtrl\n"));

  PAGED_CODE();

  //
  // initialize variables
  //
  device = WdfIoQueueGetDevice(Queue);
  pDevContext = GetDeviceContext(device);

  switch(IoControlCode) {
    case IOCTL_RIO500_RESET_PIPE:
      status = ResetPipe(pDevContext->ReadPipe);
      if (NT_SUCCESS(status)) {
        status = ResetPipe(pDevContext->WritePipe);
      }
      break;

    case IOCTL_RIO500_GET_CONFIG_DESCRIPTOR:
      if (pDevContext->UsbConfigurationDescriptor) {
        length = pDevContext->UsbConfigurationDescriptor->wTotalLength;

        status = WdfRequestRetrieveOutputBuffer(Request, length, &ioBuffer, &bufLength);
        if (!NT_SUCCESS(status)) {
          Rio500_DbgPrint(1, ("WdfRequestRetrieveInputBuffer failed\n"));
          break;
        }

        RtlCopyMemory(ioBuffer, pDevContext->UsbConfigurationDescriptor, length);
        status = STATUS_SUCCESS;
      } else {
        status = STATUS_INVALID_DEVICE_STATE;
      }
      break;

    case IOCTL_RIO500_RESET_DEVICE:
      status = ResetDevice(device);
      break;

    case IOCTL_RIO500_RIO_COMMAND:
#ifdef _WIN64
      if (IoIs32bitProcess(NULL)) {
        bufLength = sizeof(RIO_IOCTL_BLOCK) - sizeof(DWORD32);
        isWowRequest = TRUE;
      } else
#endif // _WIN64
      {
        bufLength = sizeof(RIO_IOCTL_BLOCK);
      }
      status = WdfRequestRetrieveInputBuffer(
        Request,
        bufLength,
        &ioBufferRio,
        NULL
      );

      if (NT_SUCCESS(status)) {
#ifdef _WIN64
        if (isWowRequest) {
          ioBuffer = (PVOID)ioBufferRio->MsgData.DataWow;
        } else
#endif // _WIN64
        {
          ioBuffer = ioBufferRio->MsgData.Data;
        }
        if (ioBufferRio->MsgLength != 0 && ioBuffer != NULL) {
          pMdl = IoAllocateMdl(
            ioBuffer,
            ioBufferRio->MsgLength,
            FALSE,
            FALSE,
            NULL
          );
          MmProbeAndLockPages(pMdl, (KPROCESSOR_MODE)KernelMode, IoModifyAccess);
        }

        memset(&urb, 0, sizeof(urb));
        urb.UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
        urb.UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_VENDOR_DEVICE;
        urb.UrbControlVendorClassRequest.TransferBuffer = NULL;
        urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0x00;
        urb.UrbControlVendorClassRequest.TransferBufferLength = ioBufferRio->MsgLength;
        urb.UrbControlVendorClassRequest.TransferBufferMDL = pMdl;
        urb.UrbControlVendorClassRequest.Request = ioBufferRio->RequestCode;
        urb.UrbControlVendorClassRequest.Value = ioBufferRio->MsgValue;
        urb.UrbControlVendorClassRequest.Index = ioBufferRio->MsgIndex;
        urb.UrbControlVendorClassRequest.TransferFlags = USBD_SHORT_TRANSFER_OK;
        if (ioBufferRio->RequestType & 0x80) {
          urb.UrbControlVendorClassRequest.TransferFlags |= USBD_TRANSFER_DIRECTION_IN;
        }
        urb.UrbControlVendorClassRequest.UrbLink = NULL;
      
        WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memoryDesc, &urb, sizeof(urb));
        status = WdfIoTargetSendInternalIoctlOthersSynchronously(
          WdfDeviceGetIoTarget(device),
          Request,
          IOCTL_INTERNAL_USB_SUBMIT_URB,
          &memoryDesc,
          NULL,
          NULL,
          NULL,
          NULL
        );

        if (pMdl != NULL) {
          MmUnlockPages(pMdl);
          IoFreeMdl(pMdl);
        }
      }
      break;

    default:
      status = STATUS_INVALID_DEVICE_REQUEST;
      break;
  }

  WdfRequestCompleteWithInformation(Request, status, length);

  Rio500_DbgPrint(3, ("Exit Rio500_DispatchDevCtrl\n"));
}