VOID
FilterForwardRequest(
    IN WDFREQUEST Request,
    IN WDFIOTARGET Target
    )
/*++
Routine Description:

    Passes a request on to the lower driver.

--*/
{
    WDF_REQUEST_SEND_OPTIONS options;
    BOOLEAN ret;
    NTSTATUS status;

    //
    // We are not interested in post processing the IRP so 
    // fire and forget.
    //
    WDF_REQUEST_SEND_OPTIONS_INIT(&options,
                                  WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

    ret = WdfRequestSend(Request, Target, &options);

    if (ret == FALSE) {
        status = WdfRequestGetStatus (Request);
        KdPrint( ("WdfRequestSend failed: 0x%x\n", status));
        WdfRequestComplete(Request, status);
    }

    return;
}
NTSTATUS
kmdf1394_SubmitIrpSynch (
                         IN WDFIOTARGET IoTarget,
                         IN WDFREQUEST Request,
                         IN PIRB Irb)
/*++

Routine Description:

    Synchronous Irp submission routine

Arguments:

    IoTarget - pointer to the IoTarget object.

    Request - the WDF Request packet to use

    Irb - 1394 I/O Request Block to submit

Return Value:

    NTSTATUS value
--*/
{
    NTSTATUS ntStatus = STATUS_SUCCESS;

    WDF_REQUEST_SEND_OPTIONS option;
    WDF_MEMORY_DESCRIPTOR descriptor;

    UNREFERENCED_PARAMETER (Request);

    ENTER ("kmdf1394_SubmitIrpSynch");

    ASSERT (KeGetCurrentIrql() < DISPATCH_LEVEL);
    ASSERT (Irb);

    WDF_REQUEST_SEND_OPTIONS_INIT (&option, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER (&descriptor, Irb, sizeof (IRB));

    ntStatus = WdfIoTargetSendInternalIoctlOthersSynchronously (
        IoTarget, 
        NULL, 
        IOCTL_1394_CLASS, 
        &descriptor, 
        NULL, 
        NULL, 
        &option, 
        NULL);
    if (!NT_SUCCESS(ntStatus)) 
    {
        TRACE(TL_ERROR, ("WdfIoTargetSendInternalIoctlSynchronously " 
            "Failed with status %x\n",ntStatus));
    }

    EXIT ("kmdf1394_SubmitIrpSynch", ntStatus);

    return ntStatus;
} //kmdf1394_SubmitIrpSynch
static VOID
XenVbd_StopRing(PXENVBD_DEVICE_DATA xvdd, BOOLEAN suspend) {
  PXENVBD_FILTER_DATA xvfd = (PXENVBD_FILTER_DATA)xvdd->xvfd;
  NTSTATUS status;
  WDFREQUEST request;
  WDF_REQUEST_SEND_OPTIONS send_options;
  IO_STACK_LOCATION stack;
  SCSI_REQUEST_BLOCK srb;
  SRB_IO_CONTROL sic;

  FUNCTION_ENTER();
  
  /* send a 'stop' down if we are suspending */
  if (suspend) {
    status = WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, xvfd->wdf_target, &request);
    FUNCTION_MSG("WdfRequestCreate = %08x\n", status);

    RtlZeroMemory(&stack, sizeof(IO_STACK_LOCATION));
    stack.MajorFunction = IRP_MJ_SCSI;
    stack.MinorFunction = IRP_MN_SCSI_CLASS;
    stack.Parameters.Scsi.Srb = &srb;

    RtlZeroMemory(&srb, SCSI_REQUEST_BLOCK_SIZE);
    srb.SrbFlags = SRB_FLAGS_BYPASS_FROZEN_QUEUE | SRB_FLAGS_NO_QUEUE_FREEZE;
    srb.Length = SCSI_REQUEST_BLOCK_SIZE;
    srb.PathId = 0;
    srb.TargetId = 0;
    srb.Lun = 0;
    srb.OriginalRequest = WdfRequestWdmGetIrp(request);
    srb.Function = SRB_FUNCTION_IO_CONTROL;
    srb.DataBuffer = &sic;
    
    RtlZeroMemory(&sic, sizeof(SRB_IO_CONTROL));
    sic.HeaderLength = sizeof(SRB_IO_CONTROL);
    memcpy(sic.Signature, XENVBD_CONTROL_SIG, 8);
    sic.Timeout = 60;
    sic.ControlCode = XENVBD_CONTROL_STOP;
    
    WdfRequestWdmFormatUsingStackLocation(request, &stack);
    
    WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);
    if (!WdfRequestSend(request, xvfd->wdf_target, &send_options)) {
      FUNCTION_MSG("Request was _NOT_ sent\n");
    }
    #if DBG
    status = WdfRequestGetStatus(request);
    FUNCTION_MSG("Request Status = %08x\n", status);
    FUNCTION_MSG("SRB Status = %08x\n", srb.SrbStatus);
    #endif

    WdfObjectDelete(request);
  }
  
  status = XnWriteInt32(xvdd->handle, XN_BASE_FRONTEND, "state", XenbusStateClosing);

  FUNCTION_EXIT();
}
// Pass down Idle notification request to lower driver
//
NTSTATUS HidFx2SendIdleNotification(_In_ WDFREQUEST hRequest)
{
    NTSTATUS                   status = STATUS_SUCCESS;
    WDF_REQUEST_SEND_OPTIONS   options;
    WDFIOTARGET                hNextLowerDriver;
    WDFDEVICE                  hDevice;
    PIO_STACK_LOCATION         pCurrentIrpStack = NULL;
    IO_STACK_LOCATION          nextIrpStack;

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Entry\n");

    hDevice = WdfIoQueueGetDevice(WdfRequestGetIoQueue(hRequest));
    pCurrentIrpStack = IoGetCurrentIrpStackLocation(WdfRequestWdmGetIrp(hRequest));

    // Convert the request to corresponding USB Idle notification request
    if (pCurrentIrpStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO))
    {
        ASSERT(sizeof(HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO) == sizeof(USB_IDLE_CALLBACK_INFO));
        #pragma warning(suppress :4127)  // conditional expression is constant warning
        if (sizeof(HID_SUBMIT_IDLE_NOTIFICATION_CALLBACK_INFO) == sizeof(USB_IDLE_CALLBACK_INFO))
        {
            // prepare next stack location
            RtlZeroMemory(&nextIrpStack, sizeof(IO_STACK_LOCATION));
            nextIrpStack.MajorFunction = pCurrentIrpStack->MajorFunction;
            nextIrpStack.Parameters.DeviceIoControl.InputBufferLength = pCurrentIrpStack->Parameters.DeviceIoControl.InputBufferLength;
            nextIrpStack.Parameters.DeviceIoControl.Type3InputBuffer = pCurrentIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
            nextIrpStack.Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION;
            nextIrpStack.DeviceObject = WdfIoTargetWdmGetTargetDeviceObject(WdfDeviceGetIoTarget(hDevice));

            // Format the I/O request for the driver's local I/O target by using the contents of the specified WDM I/O stack location structure.
            WdfRequestWdmFormatUsingStackLocation(hRequest, &nextIrpStack);

            // Send the request down using Fire and forget option.
            WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);
            hNextLowerDriver = WdfDeviceGetIoTarget(hDevice);
            if (WdfRequestSend(hRequest, hNextLowerDriver, &options) == FALSE)
            {
                status = STATUS_UNSUCCESSFUL;
            }
        }
        else // Incorrect DeviceIoControl.InputBufferLength
        {
            status = STATUS_INFO_LENGTH_MISMATCH;
            TraceErr(DBG_IOCTL, "(%!FUNC!) Incorrect DeviceIoControl.InputBufferLength, %!STATUS!\n", status);
            return status;
        }
    }
    else // DeviceIoControl.InputBufferLength too small
    {
        status = STATUS_BUFFER_TOO_SMALL;
        TraceErr(DBG_IOCTL, "(%!FUNC!) DeviceIoControl.InputBufferLength too small, %!STATUS!\n", status);
        return status;
    }

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit = %!STATUS!\n", status);
    return status;
}
Exemple #5
0
void MouseTrapEvtIoInternalDeviceControl(WDFQUEUE queue, WDFREQUEST request, size_t outputBufferLength, size_t inputBufferLength, ULONG ioControlCode) {
	UNREFERENCED_PARAMETER(outputBufferLength);
	UNREFERENCED_PARAMETER(inputBufferLength);

	NTSTATUS status = STATUS_SUCCESS;

	PAGED_CODE(); // Ensure paging is allowed in current IRQL

	// Get extension data
	WDFDEVICE hDevice = WdfIoQueueGetDevice(queue);
	PDEVICE_CONTEXT context = DeviceGetContext(hDevice);

	if(ioControlCode == IOCTL_INTERNAL_MOUSE_CONNECT) {
		// Only allow one connection.
		if(context->UpperConnectData.ClassService == NULL) {
			// Copy the connection parameters to the device extension.
			PCONNECT_DATA connectData;
			size_t length;
			status = WdfRequestRetrieveInputBuffer(request, sizeof(CONNECT_DATA), &connectData, &length);
			if(NT_SUCCESS(status)) {
				// Hook into the report chain (I am not sure this is correct)
				context->UpperConnectData = *connectData;
				connectData->ClassDeviceObject = WdfDeviceWdmGetDeviceObject(hDevice);

				#pragma warning(push)
				#pragma warning(disable:4152)
				connectData->ClassService = MouseTrapServiceCallback;
				#pragma warning(pop)
			}
			else {
				DebugPrint(("[MouseTrap] WdfRequestRetrieveInputBuffer failed %x\n", status));
			}
		}
		else {
			status = STATUS_SHARING_VIOLATION;
		}
	}
	else if(ioControlCode == IOCTL_INTERNAL_MOUSE_DISCONNECT) {
		status = STATUS_NOT_IMPLEMENTED;
	}

	// Complete on error
	if(!NT_SUCCESS(status)) {
		WdfRequestComplete(request, status);
		return;
	}

	// Dispatch to higher level driver
	WDF_REQUEST_SEND_OPTIONS options;
	WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

	if(WdfRequestSend(request, WdfDeviceGetIoTarget(hDevice), &options) == FALSE) {
		NTSTATUS status = WdfRequestGetStatus(request);
		DebugPrint(("[MouseTrap] WdfRequestSend failed: 0x%x\n", status));
		WdfRequestComplete(request, status);
	}
}
static VOID
XenVbd_SendEvent(WDFDEVICE device) {
  PXENVBD_FILTER_DATA xvfd = GetXvfd(device);
  NTSTATUS status;
  WDFREQUEST request;
  WDF_REQUEST_SEND_OPTIONS send_options;
  IO_STACK_LOCATION stack;
  PUCHAR buf;
  PSCSI_REQUEST_BLOCK srb;
  PSRB_IO_CONTROL sic;

  status = WdfRequestCreate(WDF_NO_OBJECT_ATTRIBUTES, xvfd->wdf_target, &request);
  if (status != STATUS_SUCCESS) {
    FUNCTION_MSG("WdfRequestCreate failed %08x\n", status);
    /* this is bad - event will be dropped */
    return;
  }

  buf = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK) + sizeof(SRB_IO_CONTROL) + sizeof(LARGE_INTEGER), XENVBD_POOL_TAG);
  RtlZeroMemory(buf, sizeof(SCSI_REQUEST_BLOCK) + sizeof(SRB_IO_CONTROL));
  srb = (PSCSI_REQUEST_BLOCK)(buf);
  sic = (PSRB_IO_CONTROL)(buf + sizeof(SCSI_REQUEST_BLOCK));
  
  srb->Length = sizeof(SCSI_REQUEST_BLOCK);
  srb->SrbFlags = SRB_FLAGS_BYPASS_FROZEN_QUEUE | SRB_FLAGS_NO_QUEUE_FREEZE;
  srb->PathId = 0;
  srb->TargetId = 0;
  srb->Lun = 0;
  srb->OriginalRequest = WdfRequestWdmGetIrp(request);
  srb->Function = SRB_FUNCTION_IO_CONTROL;
  srb->DataBuffer = sic;
  srb->DataTransferLength = sizeof(SCSI_REQUEST_BLOCK) + sizeof(SRB_IO_CONTROL);
  srb->TimeOutValue = (ULONG)-1;
  
  sic->HeaderLength = sizeof(SRB_IO_CONTROL);
  memcpy(sic->Signature, XENVBD_CONTROL_SIG, 8);
  sic->Timeout = (ULONG)-1;
  sic->ControlCode = XENVBD_CONTROL_EVENT;
  
  KeQuerySystemTime((PLARGE_INTEGER)((PUCHAR)buf + sizeof(SCSI_REQUEST_BLOCK) + sizeof(SRB_IO_CONTROL)));

  RtlZeroMemory(&stack, sizeof(IO_STACK_LOCATION));
  stack.MajorFunction = IRP_MJ_SCSI;
  stack.MinorFunction = IRP_MN_SCSI_CLASS;
  stack.Parameters.Scsi.Srb = srb;

  WdfRequestWdmFormatUsingStackLocation(request, &stack);
  WdfRequestSetCompletionRoutine(request, XenVbd_SendEventComplete, buf);
  
  WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, 0); //WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE);
  if (!WdfRequestSend(request, xvfd->wdf_target, &send_options)) {
    FUNCTION_MSG("Error sending request\n");
  }
}
VOID
SimSensorIoInternalDeviceControl (
    WDFQUEUE Queue,
    WDFREQUEST Request,
    size_t OutputBufferLength,
    size_t InputBufferLength,
    ULONG IoControlCode)

/*++

Description:

    The system uses IoInternalDeviceControl requests to communicate with the
    ACPI driver on the device stack. For proper operation of thermal zones,
    these requests must be forwarded unless the driver knows how to handle
    them.

--*/

{
    WDF_REQUEST_SEND_OPTIONS RequestSendOptions;
    BOOLEAN Return;
    NTSTATUS Status;

    UNREFERENCED_PARAMETER(OutputBufferLength);
    UNREFERENCED_PARAMETER(InputBufferLength);
    UNREFERENCED_PARAMETER(IoControlCode);

    DebugEnter();

    WdfRequestFormatRequestUsingCurrentType(Request);

    WDF_REQUEST_SEND_OPTIONS_INIT(
        &RequestSendOptions,
        WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

    Return = WdfRequestSend(
                Request,
                WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue)),
                &RequestSendOptions);

    if (Return == FALSE) {
        Status = WdfRequestGetStatus(Request);
        DebugPrint(SIMSENSOR_WARN,
                   "WdfRequestSend() Failed. Request Status=0x%x\n",
                   Status);

        WdfRequestComplete(Request, Status);
    }

    DebugExit();
}
//This routine sets the state of the Feature: in this case Segment Display on the USB FX2 board.
NTSTATUS SendVendorCommand(_In_ WDFDEVICE hDevice, _In_ unsigned char bVendorCommand, _In_ unsigned char bCommandData)
{
    NTSTATUS                     status = STATUS_SUCCESS;
    ULONG                        cBytesTransferred = 0;
    PDEVICE_EXTENSION            pDevContext = NULL;
    WDF_MEMORY_DESCRIPTOR        memDesc;
    WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket;
    WDF_REQUEST_SEND_OPTIONS     sendOptions;

    PAGED_CODE();

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Enter\n");

    pDevContext = GetDeviceContext(hDevice);

    TraceInfo(DBG_IOCTL, "(%!FUNC!): Command:0x%x, data: 0x%x\n", bVendorCommand, bCommandData);

    // Send the I/O with a timeout.
    // We do that because we send the I/O in the context of the user thread and if it gets stuck, it would prevent the user process from existing.
    WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT);

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_SEC(5));

    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                             BmRequestHostToDevice,
                                             BmRequestToDevice,
                                             bVendorCommand,    // Request
                                             0,                 // Value
                                             0);                // Index

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, &bCommandData, sizeof(bCommandData));

    status = WdfUsbTargetDeviceSendControlTransferSynchronously(pDevContext->hUsbDevice,
                                                                WDF_NO_HANDLE,      // Optional WDFREQUEST
                                                                &sendOptions,       // PWDF_REQUEST_SEND_OPTIONS
                                                                &controlSetupPacket,
                                                                &memDesc,
                                                                &cBytesTransferred);
    if (!NT_SUCCESS(status))
    {
        TraceErr(DBG_IOCTL, "(%!FUNC!): Failed to set Segment Display state - %!STATUS!\n", status);
    }

    TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit\n");

    return status;
}
VOID
ForwardRequestToIoTarget(
    _In_ WDFQUEUE   queue,
    _In_ WDFREQUEST request,
    _In_ size_t     length)
{
    TraceEntry();
    Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! - Queue 0x%p, Request 0x%p Length %Iu", queue, request, length);

    auto device = WdfIoQueueGetDevice(queue);
    auto context = GetDeviceContext(device);

    if (length > context->MaxLengthInBytesForRWTransfers) {
        TraceError("%!FUNC! - Buffer Length to big %Iu, Max is %Iu. Status - %!STATUS!",
            length, context->MaxLengthInBytesForRWTransfers, STATUS_BUFFER_OVERFLOW);

        WdfRequestCompleteWithInformation(request, STATUS_BUFFER_OVERFLOW, NULL);
        return;
    }

    auto targetDevice = WdfDeviceGetIoTarget(device);

    WdfRequestFormatRequestUsingCurrentType(request);

    WDF_REQUEST_SEND_OPTIONS options;

    WDF_REQUEST_SEND_OPTIONS_INIT(
        &options,
        WDF_REQUEST_SEND_OPTION_SYNCHRONOUS | WDF_REQUEST_SEND_OPTION_TIMEOUT);

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&options, WDF_ABS_TIMEOUT_IN_SEC(10));

    auto sendSuccess = WdfRequestSend(request, targetDevice, &options);
    auto status = WdfRequestGetStatus(request);
    if (!sendSuccess || !NT_SUCCESS(status))
    {
        TraceError("%!FUNC! - WdfRequestSend returned %d with status: %!STATUS!", sendSuccess, status);
        WdfRequestCompleteWithInformation(request, status, NULL);
        return;
    }

    WdfRequestComplete(request, status);
}
Exemple #10
0
_Must_inspect_result_
NTSTATUS
FxUsbDevice::SendSyncUmUrb(
    __inout PUMURB Urb,
    __in ULONGLONG Time,
    __in_opt WDFREQUEST Request,
    __in_opt PWDF_REQUEST_SEND_OPTIONS Options
    )
{
    NTSTATUS status;
    WDF_REQUEST_SEND_OPTIONS options;
    FxSyncRequest request(GetDriverGlobals(), NULL, Request);

    status = request.Initialize();
    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                            "Failed to initialize FxSyncRequest");
        return status;
    }

    if (NULL == Options) {
        Options = &options;
    }
    
    WDF_REQUEST_SEND_OPTIONS_INIT(Options, 0);
    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(Options, WDF_REL_TIMEOUT_IN_SEC(Time));
    
    status = request.m_TrueRequest->ValidateTarget(this);
    if (NT_SUCCESS(status)) {
        FxUsbUmFormatRequest(request.m_TrueRequest, &Urb->UmUrbHeader, m_pHostTargetFile);
        status = SubmitSync(request.m_TrueRequest, Options);
        if (!NT_SUCCESS(status)) {
            DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                                "FxUsbDevice SubmitSync failed");
            return status;
        }
    }

    return status;
}
Exemple #11
0
VOID
MouFilter_DispatchPassThrough(
    __in WDFREQUEST Request,
    __in WDFIOTARGET Target
)
/*++
Routine Description:

    Passes a request on to the lower driver.


--*/
{
    //
    // Pass the IRP to the target
    //

    WDF_REQUEST_SEND_OPTIONS options;
    BOOLEAN ret;
    NTSTATUS status = STATUS_SUCCESS;

    //
    // We are not interested in post processing the IRP so
    // fire and forget.
    //
    WDF_REQUEST_SEND_OPTIONS_INIT(&options,
                                  WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

    ret = WdfRequestSend(Request, Target, &options);

    if (ret == FALSE) {
        status = WdfRequestGetStatus (Request);
        DebugPrint( ("WdfRequestSend failed: 0x%x\n", status));
        WdfRequestComplete(Request, status);
    }

    return;
}
Exemple #12
0
_Must_inspect_result_
NTSTATUS
FxUsbDevice::SendSyncRequest(
    __in FxSyncRequest* Request,
    __in ULONGLONG Time
    )
{
    NTSTATUS status;
    WDF_REQUEST_SEND_OPTIONS options;

    WDF_REQUEST_SEND_OPTIONS_INIT(&options, 0);
    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&options, WDF_REL_TIMEOUT_IN_SEC(Time));

    status = SubmitSync(Request->m_TrueRequest, &options);
    if (!NT_SUCCESS(status)) {
        DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
                            "FxUsbDevice SubmitSync failed");
        goto Done;
    }

Done:
    return status;
}
Exemple #13
0
///////////////////////////////////////////////////////////////////////////////
// SmplFilterEvtIoDefault
///////////////////////////////////////////////////////////////////////////////
VOID SmplFilterEvtIoDefault(
  __in  WDFQUEUE Queue,
  __in  WDFREQUEST Request
)
{
    WDF_REQUEST_PARAMETERS RequestParameters;
    BOOLEAN bResult;

    WDF_REQUEST_PARAMETERS_INIT(&RequestParameters);
    WdfRequestGetParameters(Request, &RequestParameters);
    if(WdfRequestTypeRead == RequestParameters.Type)
    {
        DbgPrintEx( DPFLTR_IHVDRIVER_ID, 1234, "SmplFilterEvtIoDefault WdfRequestTypeRead\n");
        WdfRequestFormatRequestUsingCurrentType(Request);
        WdfRequestSetCompletionRoutine(Request, SmplFilterCompletionRoutineRead, NULL);
        bResult = WdfRequestSend(Request,
                                WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue)),
                                NULL);
    }
    else
    {
        WDF_REQUEST_SEND_OPTIONS Options;
        WDF_REQUEST_SEND_OPTIONS_INIT(&Options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

        DbgPrintEx( DPFLTR_IHVDRIVER_ID, 1234, "SmplFilterEvtIoDefault other Request type\n");

        bResult = WdfRequestSend(Request,
                                WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue)),
                                &Options);
    }

    if(FALSE == bResult)
    {
        DbgPrintEx( DPFLTR_IHVDRIVER_ID, 1234, "WdfRequestSend failed!\n");
        WdfRequestComplete(Request, WdfRequestGetStatus(Request));
    }
} // end SmplFilterEvtIoDefault
VOID MouFilter_DispatchPassThrough(_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target)
/*++
Routine Description:

    Passes a request on to the lower driver.

--*/
{
    WDF_REQUEST_SEND_OPTIONS options;
    BOOLEAN ret;
    NTSTATUS status = STATUS_SUCCESS;

    WDF_REQUEST_SEND_OPTIONS_INIT(&options, WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

    ret = WdfRequestSend(Request, Target, &options);

    if (ret == FALSE) {
        status = WdfRequestGetStatus (Request);
        DebugPrint( ("WdfRequestSend failed: 0x%x\n", status));
        WdfRequestComplete(Request, status);
    }

    return;
}           
VOID
SimSensorIoDeviceControl(
    WDFQUEUE   Queue,
    WDFREQUEST Request,
    size_t     OutputBufferLength,
    size_t     InputBufferLength,
    ULONG      IoControlCode
    )

/*++

Routine Description:

    Handles requests to read or write the simulated device state.

Arguments:

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

    Request - Supplies a handle to a framework request object. This one
        represents the IRP_MJ_DEVICE_CONTROL IRP received by the framework.

    OutputBufferLength - Supplies the length, in bytes, of the request's output
        buffer, if an output buffer is available.

    InputBufferLength - Supplies the length, in bytes, of the request's input
        buffer, if an input buffer is available.

    IoControlCode - Supplies the Driver-defined or system-defined I/O control
        code (IOCtl) that is associated with the request.

Return Value:

   VOID

--*/

{
    ULONG BytesReturned;
    WDFDEVICE Device;
    BOOLEAN Result;
    WDF_REQUEST_SEND_OPTIONS RequestSendOptions;
    NTSTATUS Status;

    UNREFERENCED_PARAMETER(InputBufferLength);
    UNREFERENCED_PARAMETER(OutputBufferLength);

    PAGED_CODE();

    Device = WdfIoQueueGetDevice(Queue);
    DebugPrint(SIMSENSOR_NOTE, "SimSensorIoDeviceControl: 0x%p\n", Device);
    BytesReturned = 0;
    switch(IoControlCode) {
    case IOCTL_THERMAL_READ_TEMPERATURE:

        //
        // This call will either complete the request or put it in the pending
        // queue.
        //

        SimSensorAddReadRequest(Device, Request);
        break;
    default:

        //
        // Unrecognized IOCtls must be forwarded down the stack.
        //

        WDF_REQUEST_SEND_OPTIONS_INIT(
            &RequestSendOptions,
            WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

        WdfRequestFormatRequestUsingCurrentType(Request);

        Result = WdfRequestSend(
                    Request,
                    WdfDeviceGetIoTarget(Device),
                    &RequestSendOptions);

        if (Result == FALSE) {
            Status = WdfRequestGetStatus(Request);
            DebugPrint(SIMSENSOR_WARN,
                       "WdfRequestSend() Failed. Request Status = 0x%x\n",
                       Status);

            WdfRequestComplete(Request, Status);
        }
        break;
    }
}
Exemple #16
0
/*++
Routine Description:

This callback is invoked when the framework received  WdfRequestTypeRead or
WdfRequestTypeWrite request. This read/write is performed in stages of
MAX_TRANSFER_SIZE. Once a stage of transfer is complete, then the
request is circulated again, until the requested length of transfer is
performed.

Arguments:

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

Request - Handle to a framework request object. This one represents
the WdfRequestTypeRead/WdfRequestTypeWrite IRP received by the framework.

Length - Length of the input/output buffer.

Return Value:

VOID
--*/
VOID ReadWriteBulkEndPoints(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN ULONG Length, IN WDF_REQUEST_TYPE RequestType)
{
    PMDL						newMdl = NULL;
	PMDL						requestMdl = NULL;
    PURB						urb = NULL;
    WDFMEMORY					urbMemory;
    ULONG						totalLength = Length;
    ULONG						stageLength = 0;
    ULONG						urbFlags = 0;
    NTSTATUS					status;
    ULONG_PTR					virtualAddress = 0;
    PREQUEST_CONTEXT			rwContext = NULL;
    PFILE_CONTEXT				fileContext = NULL;
    WDFUSBPIPE					pipe;
    WDF_USB_PIPE_INFORMATION	pipeInfo;
    WDF_OBJECT_ATTRIBUTES		objectAttribs;
    USBD_PIPE_HANDLE			usbdPipeHandle;
    PDEVICE_CONTEXT				deviceContext;
	WDF_REQUEST_SEND_OPTIONS	sendOptions;

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

    // First validate input parameters.
    deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

    if (totalLength > deviceContext->MaximumTransferSize)
	{
        PSDrv_DbgPrint(1, ("Transfer length (%d) is bigger then MaximumTransferSize (%d)!\n", totalLength, deviceContext->MaximumTransferSize));
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    if ((RequestType != WdfRequestTypeRead) && (RequestType != WdfRequestTypeWrite))
	{
        PSDrv_DbgPrint(1, ("RequestType has to be either Read or Write! (RequestType = %d)\n", RequestType));
        status = STATUS_INVALID_PARAMETER;
        goto Exit;
    }

    // Get the pipe associate with this request.
    fileContext = GetFileContext(WdfRequestGetFileObject(Request));
    pipe = fileContext->Pipe;
    WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
    WdfUsbTargetPipeGetInformation(pipe, &pipeInfo);

    if((WdfUsbPipeTypeBulk != pipeInfo.PipeType) && (WdfUsbPipeTypeInterrupt != pipeInfo.PipeType))
	{
        PSDrv_DbgPrint(1, ("Usbd pipe type is not bulk or interrupt! (PipeType = %d)\n", pipeInfo.PipeType));
        status = STATUS_INVALID_DEVICE_REQUEST;
        goto Exit;
    }

    rwContext = GetRequestContext(Request);

    if(RequestType == WdfRequestTypeRead)
	{
        status = WdfRequestRetrieveOutputWdmMdl(Request, &requestMdl);
        if(!NT_SUCCESS(status))
		{
            PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputWdmMdl failed! (Status = %x)\n", status));
            goto Exit;
        }

        urbFlags |= USBD_TRANSFER_DIRECTION_IN;
        rwContext->Read = TRUE;
        PSDrv_DbgPrint(3, ("This is a read operation...\n"));
    }
	else
	{
        status = WdfRequestRetrieveInputWdmMdl(Request, &requestMdl);
        if(!NT_SUCCESS(status))
		{
			PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputWdmMdl failed! (Status = %x)\n", status));
            goto Exit;
        }

        urbFlags |= USBD_TRANSFER_DIRECTION_OUT;
        rwContext->Read = FALSE;
        PSDrv_DbgPrint(3, ("This is a write operation...\n"));
    }


    urbFlags |= USBD_SHORT_TRANSFER_OK;

    virtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(requestMdl);

    // The transfer request is for totalLength. We can perform a max of MAX_TRANSFER_SIZE in each stage.
    if (totalLength > MAX_TRANSFER_SIZE)
	{
        stageLength = MAX_TRANSFER_SIZE;
    }
    else
	{
        stageLength = totalLength;
    }

    newMdl = IoAllocateMdl((PVOID)virtualAddress, totalLength, FALSE, FALSE, NULL);
    if (newMdl == NULL)
	{
        PSDrv_DbgPrint(1, ("IoAllocateMdl failed! (newMdl is NULL)\n"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    // Map the portion of user-buffer described by an mdl to another mdl
    IoBuildPartialMdl(requestMdl, newMdl, (PVOID)virtualAddress, stageLength);

    WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs);
    objectAttribs.ParentObject = Request;

    status = WdfMemoryCreate(&objectAttribs, NonPagedPool, POOL_TAG, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), &urbMemory, (PVOID*)&urb);
    if (!NT_SUCCESS(status))
	{
        PSDrv_DbgPrint(1, ("WdfMemoryCreate for urbMemory failed! (Status = %x)\n", status));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    usbdPipeHandle = WdfUsbTargetPipeWdmGetPipeHandle(pipe);

    UsbBuildInterruptOrBulkTransferRequest(urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), usbdPipeHandle, NULL, newMdl, stageLength, urbFlags, NULL);

    status = WdfUsbTargetPipeFormatRequestForUrb(pipe, Request, urbMemory, NULL);
    if (!NT_SUCCESS(status))
	{
        PSDrv_DbgPrint(1, ("WdfUsbTargetPipeFormatRequestForUrb failed! (Status = %x)\n", status));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);

    // Set REQUEST_CONTEXT parameters.
    rwContext->UrbMemory       = urbMemory;
    rwContext->Mdl             = newMdl;
    rwContext->Length          = totalLength - stageLength;
    rwContext->Numxfer         = 0;
    rwContext->VirtualAddress  = virtualAddress + stageLength;

	// Set the timeout
	if (fileContext->nTimeOut != 0)
	{
		WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT);
		WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(fileContext->nTimeOut));

		PSDrv_DbgPrint(3, ("Pipe timeout is set to: %d\n", fileContext->nTimeOut));

		if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), &sendOptions))
		{
			status = WdfRequestGetStatus(Request);
			ASSERT(!NT_SUCCESS(status));
		}
	}
	else
	{
		if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS))
		{
			status = WdfRequestGetStatus(Request);
			ASSERT(!NT_SUCCESS(status));
		}
	}

Exit:
    if (!NT_SUCCESS(status))
	{
        WdfRequestCompleteWithInformation(Request, status, 0);

        if (newMdl != NULL)
		{
            IoFreeMdl(newMdl);
        }
    }

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

    return;
}
Exemple #17
0
NTSTATUS 
GetSwitchState(
    _In_ PDEVICE_CONTEXT DevContext, 
    _In_ PSWITCH_STATE SwitchState
    )
/*++

Routine Description

    This routine gets the state of the switches on the board

Arguments:

    DevContext - One of our device extensions

Return Value:

    NT status value

--*/
{
    NTSTATUS status;
    WDF_USB_CONTROL_SETUP_PACKET    controlSetupPacket;
    WDF_REQUEST_SEND_OPTIONS        sendOptions;
    WDF_MEMORY_DESCRIPTOR memDesc;
    ULONG    bytesTransferred;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> GetSwitchState\n");

    PAGED_CODE();

    WDF_REQUEST_SEND_OPTIONS_INIT(
                                  &sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT
                                  );

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(
                                         &sendOptions,
                                         DEFAULT_CONTROL_TRANSFER_TIMEOUT
                                         );

    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestDeviceToHost,
                                        BmRequestToDevice,
                                        USBFX2LK_READ_SWITCHES, // Request
                                        0, // Value
                                        0); // Index

    SwitchState->SwitchesAsUChar = 0;

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc,
                                    SwitchState,
                                    sizeof(SWITCH_STATE));

    status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                                DevContext->UsbDevice,
                                                NULL, // Optional WDFREQUEST
                                                &sendOptions,
                                                &controlSetupPacket,
                                                &memDesc,
                                                &bytesTransferred);

    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                "GetSwitchState: Failed to Get switches - 0x%x \n", status);

    } else {
        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,
            "GetSwitchState: Switch mask is 0x%x\n", SwitchState->SwitchesAsUChar);
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- GetSwitchState\n");

    return status;

}
Exemple #18
0
NTSTATUS 
SetSevenSegmentState(
    _In_ PDEVICE_CONTEXT DevContext, 
    _In_ PUCHAR SevenSegment
    )
/*++

Routine Description

    This routine sets the state of the 7 segment display on the board

Arguments:

    DevContext - One of our device extensions

    SevenSegment - desired state of the 7 segment display

Return Value:

    NT status value

--*/
{
    NTSTATUS status;
    WDF_USB_CONTROL_SETUP_PACKET    controlSetupPacket;
    WDF_REQUEST_SEND_OPTIONS        sendOptions;
    WDF_MEMORY_DESCRIPTOR memDesc;
    ULONG    bytesTransferred;

    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> SetSevenSegmentState\n");

    WDF_REQUEST_SEND_OPTIONS_INIT(
                                  &sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT
                                  );

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(
                                         &sendOptions,
                                         DEFAULT_CONTROL_TRANSFER_TIMEOUT
                                         );

    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestHostToDevice,
                                        BmRequestToDevice,
                                        USBFX2LK_SET_7SEGMENT_DISPLAY, // Request
                                        0, // Value
                                        0); // Index

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc,
                                    SevenSegment,
                                    sizeof(UCHAR));

    status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                                DevContext->UsbDevice,
                                                NULL, // Optional WDFREQUEST
                                                &sendOptions,
                                                &controlSetupPacket,
                                                &memDesc,
                                                &bytesTransferred);

    if(!NT_SUCCESS(status)) {

        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
            "SetSevenSegmentState: Failed to set 7 Segment state - 0x%x \n", status);

    } else {

        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,
            "SetSevenSegmentState: 7 Segment mask is 0x%x\n", *SevenSegment);

    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- SetSevenSegmentState\n");

    return status;

}
Exemple #19
0
NTSTATUS 
GetSevenSegmentState(
    _In_ PDEVICE_CONTEXT DevContext, 
    _Out_ PUCHAR SevenSegment
    )
/*++

Routine Description

    This routine gets the state of the 7 segment display on the board
    by sending a synchronous control command.

    NOTE: It's not a good practice to send a synchronous request in the
          context of the user thread because if the transfer takes long
          time to complete, you end up holding the user thread.

          I'm choosing to do synchronous transfer because a) I know this one
          completes immediately b) and for demonstration.

Arguments:

    DevContext - One of our device extensions

    SevenSegment - receives the state of the 7 segment display

Return Value:

    NT status value

--*/
{
    NTSTATUS status;
    WDF_USB_CONTROL_SETUP_PACKET    controlSetupPacket;
    WDF_REQUEST_SEND_OPTIONS        sendOptions;
    
    WDF_MEMORY_DESCRIPTOR memDesc;
    ULONG    bytesTransferred;

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSetSevenSegmentState: Enter\n");

    PAGED_CODE();

    WDF_REQUEST_SEND_OPTIONS_INIT(
                                  &sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT
                                  );

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(
                                         &sendOptions,
                                         DEFAULT_CONTROL_TRANSFER_TIMEOUT
                                         );

    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestDeviceToHost,
                                        BmRequestToDevice,
                                        USBFX2LK_READ_7SEGMENT_DISPLAY, // Request
                                        0, // Value
                                        0); // Index

    //
    // Set the buffer to 0, the board will OR in everything that is set
    //
    *SevenSegment = 0;

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc,
                                    SevenSegment,
                                    sizeof(UCHAR));

    status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                    DevContext->UsbDevice,
                                    NULL, // Optional WDFREQUEST
                                    &sendOptions,
                                    &controlSetupPacket,
                                    &memDesc,
                                    &bytesTransferred);

    if(!NT_SUCCESS(status)) {

        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
            "GetSevenSegmentState: Failed to get 7 Segment state - 0x%x \n", status);
    } else {

        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,
            "GetSevenSegmentState: 7 Segment mask is 0x%x\n", *SevenSegment);
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSetSevenSegmentState: Exit\n");

    return status;

}
Exemple #20
0
NTSTATUS 
GetDevInfoLength(
    __in  PFILTER_EXTENSION filterExt, 
    __out BYTE*             pDevInfoLen
    )
/*++

Routine Description

    This routine gets the length of device info, so caller app
    can prepare proper buffer to retrieve the actual content info

Arguments:

    pDevInfoLen - One of our device extensions

Return Value:

    NT status value

--*/
{
    NTSTATUS status;

    WDF_USB_CONTROL_SETUP_PACKET    controlSetupPacket;
    WDF_REQUEST_SEND_OPTIONS        sendOptions;
    WDF_MEMORY_DESCRIPTOR           memDesc;
    ULONG    bytesTransferred;

    PAGED_CODE();

    WDF_REQUEST_SEND_OPTIONS_INIT(
                                  &sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT
                                  );

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(
                                         &sendOptions,
                                         WDF_REL_TIMEOUT_IN_SEC(5)
                                         );

    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestDeviceToHost,
                                        BmRequestToDevice,
                                        USBFX2LK_READ_DEVINFO_LEN, // Request
                                        0, // Value
                                        0); // Index

    //
    // Set the buffer to 0, the board will OR in everything that is set
    //
    *pDevInfoLen = 0;


    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc,
                                      pDevInfoLen,
                                      sizeof(BYTE));

    status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                        filterExt->UsbDevice,
                                        WDF_NO_HANDLE, // Optional WDFREQUEST
                                        &sendOptions,
                                        &controlSetupPacket,
                                        &memDesc,
                                        &bytesTransferred);

    if(!NT_SUCCESS(status)) {

		KdPrint( ("GetDevInfoLength: Failed -  0x%x \n", status));

    } else {

		KdPrint( ("GetDevInfoLength: %d \n", *pDevInfoLen ));
    }

    return status;
}
Exemple #21
0
VOID
EvtIoDeviceControl(
    IN WDFQUEUE   Queue,
    IN WDFREQUEST Request,
    IN size_t     OutputBufferLength,
    IN size_t     InputBufferLength,
    IN ULONG      IoControlCode
    )
{
    WDFDEVICE                           device;
    PDEVICE_CONTEXT                     pDevContext;
    size_t                              bytesTransferred = 0;
    NTSTATUS                            status;
    WDF_USB_CONTROL_SETUP_PACKET        controlSetupPacket;
    WDF_MEMORY_DESCRIPTOR               memDesc;
    WDFMEMORY                           memory;
    WDF_REQUEST_SEND_OPTIONS            sendOptions;

    UNREFERENCED_PARAMETER(InputBufferLength);
    UNREFERENCED_PARAMETER(OutputBufferLength);

    device = WdfIoQueueGetDevice(Queue);
    pDevContext = GetDeviceContext(device);

    switch(IoControlCode) {

    case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY:

        if(InputBufferLength < sizeof(UCHAR)) {
            status = STATUS_BUFFER_OVERFLOW;
            bytesTransferred = sizeof(UCHAR);
            break;
        }

        status = WdfRequestRetrieveInputMemory(Request, &memory);
        if (!NT_SUCCESS(status)) {
            KdPrint(("WdfRequestRetrieveMemory failed %!STATUS!", status));
            break;
        }

        WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestHostToDevice,
                                        BmRequestToDevice,
                                        USBFX2LK_SET_BARGRAPH_DISPLAY, // Request
                                        0, // Value
                                        0); // Index

        WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDesc, memory, NULL);

       //
       // Send the I/O with a timeout to avoid hanging the calling 
       // thread indefinitely.
       //
        WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT);

        WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions,
                                         WDF_REL_TIMEOUT_IN_MS(100));

        status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                        pDevContext->UsbDevice,
                                        NULL, // Optional WDFREQUEST
                                        &sendOptions, // PWDF_REQUEST_SEND_OPTIONS
                                        &controlSetupPacket,
                                        &memDesc,
                                        (PULONG)&bytesTransferred);
        if (!NT_SUCCESS(status)) {
            KdPrint(("SendControlTransfer failed %!STATUS!", status));
            break;
        }
        break;

    default:
        status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    WdfRequestCompleteWithInformation(Request, status, bytesTransferred);

    return;
}
Exemple #22
0
VOID
KbFilter_EvtIoInternalDeviceControl(
    IN WDFQUEUE      Queue,
    IN WDFREQUEST    Request,
    IN size_t        OutputBufferLength,
    IN size_t        InputBufferLength,
    IN ULONG         IoControlCode
    )
/*++

Routine Description:

    This routine is the dispatch routine for internal device control requests.
    There are two specific control codes that are of interest:

    IOCTL_INTERNAL_KEYBOARD_CONNECT:
        Store the old context and function pointer and replace it with our own.
        This makes life much simpler than intercepting IRPs sent by the RIT and
        modifying them on the way back up.

    IOCTL_INTERNAL_I8042_HOOK_KEYBOARD:
        Add in the necessary function pointers and context values so that we can
        alter how the ps/2 keyboard is initialized.

    NOTE:  Handling IOCTL_INTERNAL_I8042_HOOK_KEYBOARD is *NOT* necessary if
           all you want to do is filter KEYBOARD_INPUT_DATAs.  You can remove
           the handling code and all related device extension fields and
           functions to conserve space.

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

--*/
{
    PDEVICE_EXTENSION               devExt;
    PINTERNAL_I8042_HOOK_KEYBOARD   hookKeyboard = NULL;
    PCONNECT_DATA                   connectData = NULL;
    NTSTATUS                        status = STATUS_SUCCESS;
    size_t                          length;
    WDFDEVICE                       hDevice;
    BOOLEAN                         forwardWithCompletionRoutine = FALSE;
    BOOLEAN                         ret = TRUE;
    WDFCONTEXT                      completionContext = WDF_NO_CONTEXT;
    WDF_REQUEST_SEND_OPTIONS        options;
    WDFMEMORY                       outputMemory;
    UNREFERENCED_PARAMETER(OutputBufferLength);
    UNREFERENCED_PARAMETER(InputBufferLength);


    PAGED_CODE();

    DebugPrint(("Entered KbFilter_EvtIoInternalDeviceControl\n"));

    hDevice = WdfIoQueueGetDevice(Queue);
    devExt = FilterGetData(hDevice);

    switch (IoControlCode) {

    //
    // Connect a keyboard class device driver to the port driver.
    //
    case IOCTL_INTERNAL_KEYBOARD_CONNECT:
        //
        // Only allow one connection.
        //
        if (devExt->UpperConnectData.ClassService != NULL) {
            status = STATUS_SHARING_VIOLATION;
            break;
        }

        //
        // Get the input buffer from the request
        // (Parameters.DeviceIoControl.Type3InputBuffer).
        //
        status = WdfRequestRetrieveInputBuffer(Request,
                                    sizeof(CONNECT_DATA),
                                    &connectData,
                                    &length);
        if(!NT_SUCCESS(status)){
            DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status));
            break;
        }

        NT_ASSERT(length == InputBufferLength);

        devExt->UpperConnectData = *connectData;

        //
        // Hook into the report chain.  Everytime a keyboard packet is reported
        // to the system, KbFilter_ServiceCallback will be called
        //

        connectData->ClassDeviceObject = WdfDeviceWdmGetDeviceObject(hDevice);

#pragma warning(disable:4152)  //nonstandard extension, function/data pointer conversion

        connectData->ClassService = KbFilter_ServiceCallback;

#pragma warning(default:4152)

        break;

    //
    // Disconnect a keyboard class device driver from the port driver.
    //
    case IOCTL_INTERNAL_KEYBOARD_DISCONNECT:

        //
        // Clear the connection parameters in the device extension.
        //
        // devExt->UpperConnectData.ClassDeviceObject = NULL;
        // devExt->UpperConnectData.ClassService = NULL;

        status = STATUS_NOT_IMPLEMENTED;
        break;

    //
    // Attach this driver to the initialization and byte processing of the
    // i8042 (ie PS/2) keyboard.  This is only necessary if you want to do PS/2
    // specific functions, otherwise hooking the CONNECT_DATA is sufficient
    //
    case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD:

        DebugPrint(("hook keyboard received!\n"));

        //
        // Get the input buffer from the request
        // (Parameters.DeviceIoControl.Type3InputBuffer)
        //
        status = WdfRequestRetrieveInputBuffer(Request,
                            sizeof(INTERNAL_I8042_HOOK_KEYBOARD),
                            &hookKeyboard,
                            &length);
        if(!NT_SUCCESS(status)){
            DebugPrint(("WdfRequestRetrieveInputBuffer failed %x\n", status));
            break;
        }

        NT_ASSERT(length == InputBufferLength);

        //
        // Enter our own initialization routine and record any Init routine
        // that may be above us.  Repeat for the isr hook
        //
        devExt->UpperContext = hookKeyboard->Context;

        //
        // replace old Context with our own
        //
        hookKeyboard->Context = (PVOID) devExt;

        if (hookKeyboard->InitializationRoutine) {
            devExt->UpperInitializationRoutine =
                hookKeyboard->InitializationRoutine;
        }
        hookKeyboard->InitializationRoutine =
            (PI8042_KEYBOARD_INITIALIZATION_ROUTINE)
            KbFilter_InitializationRoutine;

        if (hookKeyboard->IsrRoutine) {
            devExt->UpperIsrHook = hookKeyboard->IsrRoutine;
        }
        hookKeyboard->IsrRoutine = (PI8042_KEYBOARD_ISR) KbFilter_IsrHook;

        //
        // Store all of the other important stuff
        //
        devExt->IsrWritePort = hookKeyboard->IsrWritePort;
        devExt->QueueKeyboardPacket = hookKeyboard->QueueKeyboardPacket;
        devExt->CallContext = hookKeyboard->CallContext;

        status = STATUS_SUCCESS;
        break;


    case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
        forwardWithCompletionRoutine = TRUE;
        completionContext = devExt;
        break;
        
    //
    // Might want to capture these in the future.  For now, then pass them down
    // the stack.  These queries must be successful for the RIT to communicate
    // with the keyboard.
    //
    case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
    case IOCTL_KEYBOARD_QUERY_INDICATORS:
    case IOCTL_KEYBOARD_SET_INDICATORS:
    case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
    case IOCTL_KEYBOARD_SET_TYPEMATIC:
        break;
    }

    if (!NT_SUCCESS(status)) {
        WdfRequestComplete(Request, status);
        return;
    }

    //
    // Forward the request down. WdfDeviceGetIoTarget returns
    // the default target, which represents the device attached to us below in
    // the stack.
    //

    if (forwardWithCompletionRoutine) {

        //
        // Format the request with the output memory so the completion routine
        // can access the return data in order to cache it into the context area
        //
        
        status = WdfRequestRetrieveOutputMemory(Request, &outputMemory); 

        if (!NT_SUCCESS(status)) {
            DebugPrint(("WdfRequestRetrieveOutputMemory failed: 0x%x\n", status));
            WdfRequestComplete(Request, status);
            return;
        }

        status = WdfIoTargetFormatRequestForInternalIoctl(WdfDeviceGetIoTarget(hDevice),
                                                         Request,
                                                         IoControlCode,
                                                         NULL,
                                                         NULL,
                                                         outputMemory,
                                                         NULL);

        if (!NT_SUCCESS(status)) {
            DebugPrint(("WdfIoTargetFormatRequestForInternalIoctl failed: 0x%x\n", status));
            WdfRequestComplete(Request, status);
            return;
        }
    
        // 
        // Set our completion routine with a context area that we will save
        // the output data into
        //
        WdfRequestSetCompletionRoutine(Request,
                                    KbFilterRequestCompletionRoutine,
                                    completionContext);

        ret = WdfRequestSend(Request,
                             WdfDeviceGetIoTarget(hDevice),
                             WDF_NO_SEND_OPTIONS);

        if (ret == FALSE) {
            status = WdfRequestGetStatus (Request);
            DebugPrint( ("WdfRequestSend failed: 0x%x\n", status));
            WdfRequestComplete(Request, status);
        }

    }
    else
    {

        //
        // We are not interested in post processing the IRP so 
        // fire and forget.
        //
        WDF_REQUEST_SEND_OPTIONS_INIT(&options,
                                      WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);

        ret = WdfRequestSend(Request, WdfDeviceGetIoTarget(hDevice), &options);

        if (ret == FALSE) {
            status = WdfRequestGetStatus (Request);
            DebugPrint(("WdfRequestSend failed: 0x%x\n", status));
            WdfRequestComplete(Request, status);
        }
        
    }

    return;
}
NTSTATUS AndroidUsbPipeFileObject::CommonBulkReadWrite(
    WDFREQUEST request,
    PMDL transfer_mdl,
    ULONG length,
    bool is_read,
    ULONG time_out,
    bool is_ioctl) {
  ASSERT_IRQL_LOW_OR_DISPATCH();

  ASSERT(IsPipeAttached());
  if (!IsPipeAttached()) {
    WdfRequestComplete(request, STATUS_INVALID_DEVICE_STATE);
    return STATUS_INVALID_DEVICE_STATE;
  }

  // Quick access check. Might be redundant though...
  ASSERT((is_read && is_input_pipe()) || (!is_read && is_output_pipe()));
  if ((is_read && is_output_pipe()) || (!is_read && is_input_pipe())) {
    WdfRequestComplete(request, STATUS_ACCESS_DENIED);
    return STATUS_ACCESS_DENIED;
  }

  // Set URB flags
  ULONG urb_flags = USBD_SHORT_TRANSFER_OK | (is_read ?
                                                USBD_TRANSFER_DIRECTION_IN :
                                                USBD_TRANSFER_DIRECTION_OUT);

  // Calculate transfer length for this stage.
  ULONG stage_len =
    (length > GetTransferGranularity()) ? GetTransferGranularity() : length;

  // Get virtual address that we're gonna use in the transfer.
  // We rely here on the fact that we're in the context of the calling thread.
  void* virtual_address = MmGetMdlVirtualAddress(transfer_mdl);

  // Allocate our private MDL for this address which we will use for the transfer
  PMDL new_mdl = IoAllocateMdl(virtual_address, length, FALSE, FALSE, NULL);
  ASSERT(NULL != new_mdl);
  if (NULL == new_mdl) {
    WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  // Map the portion of user buffer that we're going to transfer at this stage
  // to our mdl.
  IoBuildPartialMdl(transfer_mdl, new_mdl, virtual_address, stage_len);

  // Allocate memory for URB and associate it with this request
  WDF_OBJECT_ATTRIBUTES mem_attrib;
  WDF_OBJECT_ATTRIBUTES_INIT(&mem_attrib);
  mem_attrib.ParentObject = request;

  WDFMEMORY urb_mem = NULL;
  PURB urb = NULL;
  NTSTATUS status =
    WdfMemoryCreate(&mem_attrib,
                    NonPagedPool,
                    GANDR_POOL_TAG_BULKRW_URB,
                    sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
                    &urb_mem,
                    reinterpret_cast<PVOID*>(&urb));
  ASSERT(NT_SUCCESS(status) && (NULL != urb));
  if (!NT_SUCCESS(status)) {
    IoFreeMdl(new_mdl);
    WdfRequestComplete(request, STATUS_INSUFFICIENT_RESOURCES);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  // Get USB pipe handle for our pipe and initialize transfer request for it
  USBD_PIPE_HANDLE usbd_pipe_hndl = usbd_pipe();
  ASSERT(NULL != usbd_pipe_hndl);
  if (NULL == usbd_pipe_hndl) {
    IoFreeMdl(new_mdl);
    WdfRequestComplete(request, STATUS_INTERNAL_ERROR);
    return STATUS_INTERNAL_ERROR;
  }

  // Initialize URB with request information
  UsbBuildInterruptOrBulkTransferRequest(
    urb,
    sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
    usbd_pipe_hndl,
    NULL,
    new_mdl,
    stage_len,
    urb_flags,
    NULL);

  // Build transfer request
  status = WdfUsbTargetPipeFormatRequestForUrb(wdf_pipe(),
                                               request,
                                               urb_mem,
                                               NULL);
  ASSERT(NT_SUCCESS(status));
  if (!NT_SUCCESS(status)) {
    IoFreeMdl(new_mdl);
    WdfRequestComplete(request, status);
    return status;
  }

  // Initialize our request context.
  AndroidUsbWdfRequestContext* context =
    GetAndroidUsbWdfRequestContext(request);
  ASSERT(NULL != context);
  if (NULL == context) {
    IoFreeMdl(new_mdl);
    WdfRequestComplete(request, STATUS_INTERNAL_ERROR);
    return STATUS_INTERNAL_ERROR;
  }

  context->object_type = AndroidUsbWdfObjectTypeRequest;
  context->urb_mem = urb_mem;
  context->transfer_mdl = transfer_mdl;
  context->mdl = new_mdl;
  context->length = length;
  context->transfer_size = stage_len;
  context->num_xfer = 0;
  context->virtual_address = virtual_address;
  context->is_read = is_read;
  context->initial_time_out = time_out;
  context->is_ioctl = is_ioctl;

  // Set our completion routine
  WdfRequestSetCompletionRoutine(request,
                                 CommonReadWriteCompletionEntry,
                                 this);

  // Init send options (our timeout goes here)
  WDF_REQUEST_SEND_OPTIONS send_options;
  if (0 != time_out) {
    WDF_REQUEST_SEND_OPTIONS_INIT(&send_options, WDF_REQUEST_SEND_OPTION_TIMEOUT);
    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&send_options, WDF_REL_TIMEOUT_IN_MS(time_out));
  }

  // Timestamp first WdfRequestSend
  KeQuerySystemTime(&context->sent_at);

  // Send request asynchronously.
  if (WdfRequestSend(request, wdf_pipe_io_target(),
                     (0 == time_out) ? WDF_NO_SEND_OPTIONS : &send_options)) {
    return STATUS_SUCCESS;
  }

  // Something went wrong here
  status = WdfRequestGetStatus(request);
  ASSERT(!NT_SUCCESS(status));
  GoogleDbgPrint("\n!!!!! CommonBulkReadWrite: WdfRequestGetStatus (is_read = %u) failed: %08X",
           is_read, status);
  WdfRequestCompleteWithInformation(request, status, 0);

  return status;
}
VOID XferCtrl (
    __in WDFQUEUE Queue,
    __in WDFREQUEST Request,
    __in size_t InputBufferLength,
    __in size_t OutputBufferLength)
{
	NTSTATUS                status;
	PDEVICE_CONTEXT         deviceContext;
	PREQUEST_CONTEXT        requestContext;
	WDFMEMORY				transferMemory;
	PWDF_USB_CONTROL_SETUP_PACKET setupPacket;
	WDF_REQUEST_SEND_OPTIONS sendOptions;
	WDFMEMORY_OFFSET		_transferOffset;
	PWDFMEMORY_OFFSET		transferOffset = &_transferOffset;

	UNREFERENCED_PARAMETER(InputBufferLength);
	UNREFERENCED_PARAMETER(OutputBufferLength);

	deviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
	requestContext = GetRequestContext(Request);

	setupPacket = (PWDF_USB_CONTROL_SETUP_PACKET)&requestContext->IoControlRequest.control;
	USBDBG("bmDir=%s bmType=%s bmRecipient=%s bmReserved=%03u bRequest=%u wIndex=%u wValue=%u wLength=%u\n",
	       GetBmRequestDirString(setupPacket->Packet.bm.Request.Dir),
	       GetBmRequestTypeString(setupPacket->Packet.bm.Request.Type),
	       GetBmRequestRecipientString(setupPacket->Packet.bm.Request.Recipient),
	       setupPacket->Packet.bm.Request.Reserved,
	       setupPacket->Packet.bRequest,
	       setupPacket->Packet.wIndex.Value,
	       setupPacket->Packet.wValue.Value,
	       setupPacket->Packet.wLength);

	// If the device and config descriptor requests are not handled they will be the "true"
	// descriptors directly from the device. i.e. if the device has two unassociated interfaces
	// the composite layer will split it into two but each virtual device interface would show
	// both interface deacriptors.
	//
	if (setupPacket->Packet.bm.Request.Dir == BMREQUEST_DEVICE_TO_HOST &&
	        setupPacket->Packet.bm.Request.Type == BMREQUEST_STANDARD &&
	        setupPacket->Packet.bRequest == USB_REQUEST_GET_DESCRIPTOR)
	{
		UCHAR descriptorType = setupPacket->Packet.wValue.Bytes.HiByte;
		// UCHAR descriptorIndex = setupPacket->Packet.wValue.Bytes.LowByte;
		ULONG descriptorSize = 0;
		PVOID descriptorIn = NULL;
		PVOID outputBuffer = NULL;
		size_t outputBufferLength = 0;

		if (requestContext->IoControlCode == LIBUSB_IOCTL_GET_DESCRIPTOR)
		{
			switch(descriptorType)
			{
			case USB_DESCRIPTOR_TYPE_DEVICE:
				descriptorSize = sizeof(deviceContext->UsbDeviceDescriptor);
				descriptorIn = &deviceContext->UsbDeviceDescriptor;
				break;
			case USB_DESCRIPTOR_TYPE_CONFIGURATION:
				if (setupPacket->Packet.wValue.Bytes.LowByte == 0)
				{
					descriptorSize = deviceContext->ConfigurationDescriptorSize;
					descriptorIn = deviceContext->UsbConfigurationDescriptor;
				}
				else
				{
					// we only support the one for now. ;)
					WdfRequestCompleteWithInformation(Request, STATUS_NO_MORE_ENTRIES, 0);
					return;
				}
				break;
			}

			if (descriptorIn && descriptorSize)
			{
				// handle (or fail) this standard request here.
				status = WdfRequestRetrieveOutputBuffer(Request, 2, &outputBuffer, &outputBufferLength);
				if (NT_SUCCESS(status))
				{
					descriptorSize = (ULONG)min(descriptorSize, outputBufferLength);
					RtlCopyMemory(outputBuffer, descriptorIn, descriptorSize);
					WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, descriptorSize);
					return;
				}
				USBERR("WdfRequestRetrieveOutputBuffer failed. status=%Xh\n", status);
				WdfRequestCompleteWithInformation(Request, status, 0);
				return;
			}
		}
	}

	if (METHOD_FROM_CTL_CODE(requestContext->IoControlCode) == METHOD_BUFFERED &&
	        requestContext->RequestType == WdfRequestTypeWrite)
	{
		// support for some of the legacy LIBUSB_IOCTL codes which place the data input
		// buffer at the end of the libusb_request structure.
		status = WdfRequestRetrieveInputMemory(Request, &transferMemory);
		if (!NT_SUCCESS(status))
		{
			USBERR("WdfRequestRetrieveInputMemory failed. status=%Xh\n", status);
			goto Exit;
		}

		if (requestContext->Length < sizeof(libusb_request))
		{
			// this can never happen because the input buffer length is checked for
			// this by the default IoControl event.
			status = STATUS_BUFFER_TOO_SMALL;
			USBERR("input buffer length is less than sizeof(libusb_request) status=%Xh\n", status);
			goto Exit;
		}

		transferOffset->BufferOffset = sizeof(libusb_request);
		transferOffset->BufferLength = requestContext->Length - sizeof(libusb_request);

		if (transferOffset->BufferLength == 0)
		{
			// this is okay but no input data means transferOffset->BufferOffset is pointing
			// to invalid memory; because the length is also zero it is still most likely safe.
			transferOffset = NULL;
			transferMemory = NULL;
		}
	}
	else
	{
		// native control transfers are direct; data comes from/goes to the out buffer whether reading or writing.
		transferOffset = NULL;
		status = WdfRequestRetrieveOutputMemory(Request, &transferMemory);
		if (!NT_SUCCESS(status) && status != STATUS_BUFFER_TOO_SMALL)
		{
			USBERR("WdfRequestRetrieveOutputMemory failed. status=%Xh\n", status);
			goto Exit;
		}

		if (status == STATUS_BUFFER_TOO_SMALL)
		{
			// zero length transfer buffer, this is okay.
			transferMemory = NULL;
			USBMSG("zero-length transfer buffer\n");
		}
	}



	status = WdfUsbTargetDeviceFormatRequestForControlTransfer(
	             deviceContext->WdfUsbTargetDevice,
	             Request,
	             setupPacket,
	             transferMemory,
	             transferOffset);

	if (!NT_SUCCESS(status))
	{
		USBERR("WdfUsbTargetDeviceFormatRequestForControlTransfer failed. status=%Xh\n", status);
		goto Exit;
	}

	WdfRequestSetCompletionRoutine(Request,
	                               XferCtrlComplete,
	                               NULL);

	WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, 0);
	status = SetRequestTimeout(requestContext, Request, &sendOptions);
	if (!NT_SUCCESS(status))
	{
		USBERR("SetRequestTimeout failed. status=%Xh\n", status);
		goto Exit;
	}

	if (!WdfRequestSend(Request,
	                    WdfUsbTargetDeviceGetIoTarget(deviceContext->WdfUsbTargetDevice),
	                    &sendOptions))
	{
		status = WdfRequestGetStatus(Request);
		USBERR("WdfRequestSend failed. status=%Xh\n", status);
	}
	else
	{
		USBMSGN("[Ok] status=%Xh", status);
		return;
	}


Exit:
	if (!NT_SUCCESS(status))
	{
		WdfRequestCompleteWithInformation(Request, status, 0);
	}

	return;
}
Exemple #25
0
NTSTATUS 
ReenumerateDevice(
    _In_ PDEVICE_CONTEXT DevContext
    )
/*++

Routine Description

    This routine re-enumerates the USB device.

Arguments:

    pDevContext - One of our device extensions

Return Value:

    NT status value

--*/
{
    NTSTATUS status;
    WDF_USB_CONTROL_SETUP_PACKET    controlSetupPacket;
    WDF_REQUEST_SEND_OPTIONS        sendOptions;
    GUID                            activity;
    
    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,"--> ReenumerateDevice\n");

    WDF_REQUEST_SEND_OPTIONS_INIT(
                                  &sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT
                                  );

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(
                                         &sendOptions,
                                         DEFAULT_CONTROL_TRANSFER_TIMEOUT
                                         );
              
    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestHostToDevice,
                                        BmRequestToDevice,
                                        USBFX2LK_REENUMERATE, // Request
                                        0, // Value
                                        0); // Index


    status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                        DevContext->UsbDevice,
                                        WDF_NO_HANDLE, // Optional WDFREQUEST
                                        &sendOptions,
                                        &controlSetupPacket,
                                        NULL, // MemoryDescriptor
                                        NULL); // BytesTransferred

    if(!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                    "ReenumerateDevice: Failed to Reenumerate - 0x%x \n", status);
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,"<-- ReenumerateDevice\n");

    //
    // Send event to eventlog
    //

    activity = DeviceToActivityId(WdfObjectContextGetObject(DevContext));
    EventWriteDeviceReenumerated(DevContext->DeviceName,
                                 DevContext->Location,
                                 status);
   
    return status;

}
Exemple #26
0
/*++
Routine Description:

This routine sets a property on a pipe.

Arguments:

pDeviceContext - Device context handle
pControlTransfer - The control transfer property struct

Return Value:

NT status value
--*/
NTSTATUS ControlTransfer(IN PDEVICE_CONTEXT pDeviceContext, IN PSUSBDRV_CONTROL_TRANSFER* pControlTransfer, IN OUT PUCHAR pControlBuffer, IN size_t nControlBufferSize, OUT ULONG* pLength)
{
	NTSTATUS						status = STATUS_SUCCESS;
	unsigned int					nTimeout = PSUSBDRV_DEFAULT_CONTROL_TIMEOUT;
	WDF_REQUEST_SEND_OPTIONS		sendOptions;
	WDF_USB_CONTROL_SETUP_PACKET	controlSetupPacket;
	WDF_MEMORY_DESCRIPTOR			memDesc;

	PAGED_CODE();

	RtlZeroMemory(&controlSetupPacket, sizeof(WDF_USB_CONTROL_SETUP_PACKET));

	controlSetupPacket.Packet.bm.Request.Dir = pControlTransfer->cDirection;
	controlSetupPacket.Packet.bm.Request.Type = pControlTransfer->cRequestType;
	controlSetupPacket.Packet.bm.Request.Recipient = BmRequestToDevice;
	controlSetupPacket.Packet.bRequest = pControlTransfer->cRequest;
	controlSetupPacket.Packet.wValue.Value = pControlTransfer->nValue;
	controlSetupPacket.Packet.wIndex.Value = pControlTransfer->nIndex;

	PSDrv_DbgPrint(3, ("ControlTransfer: Dir:%d Type:%d Request:%d Value:%d Index:%d.\n", pControlTransfer->cDirection, pControlTransfer->cRequestType,  pControlTransfer->cRequest, pControlTransfer->nValue, pControlTransfer->nIndex));

	if (pControlTransfer->nTimeout != 0)
	{
		if (pControlTransfer->nTimeout > PSUSBDRV_DEFAULT_CONTROL_TIMEOUT)
		{
			PSDrv_DbgPrint(3, ("ControlTransfer: Timeout was truncated from %d to %d!\n", pControlTransfer->nTimeout, PSUSBDRV_DEFAULT_CONTROL_TIMEOUT));

			nTimeout = PSUSBDRV_DEFAULT_CONTROL_TIMEOUT;
		}
		else
		{
			nTimeout = pControlTransfer->nTimeout;
		}
	}

	WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT);
	WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(nTimeout));	

	PSDrv_DbgPrint(3, ("ControlTransfer: Timeout is set to: %d.\n", nTimeout));

	PSDrv_DbgPrint(3, ("ControlTransfer: Performing the control transfer...\n"));

	if (pControlBuffer != NULL)
	{
		PSDrv_DbgPrint(3, ("ControlTransfer: Buffer:%x Length:%d\n", pControlBuffer, nControlBufferSize));

		if (nControlBufferSize == 0)
		{
			PSDrv_DbgPrint(3, ("ControlTransfer: pControlBuffer is not NULL but nControlBufferSize is 0!\n"));

			return (STATUS_INVALID_PARAMETER);
		}

		WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, pControlBuffer, (ULONG)nControlBufferSize);

		status = WdfUsbTargetDeviceSendControlTransferSynchronously(pDeviceContext->WdfUsbTargetDevice, WDF_NO_HANDLE, &sendOptions, &controlSetupPacket, &memDesc, pLength);
	}
	else
	{
		status = WdfUsbTargetDeviceSendControlTransferSynchronously(pDeviceContext->WdfUsbTargetDevice, WDF_NO_HANDLE, &sendOptions, &controlSetupPacket, NULL, pLength);
	}

	PSDrv_DbgPrint(3, ("ControlTransfer: Finished! Status=%x BytesTransferred=%d\n", status, *pLength));

	return status;
}
Exemple #27
0
NTSTATUS 
SetBarGraphState(
    _In_ PDEVICE_CONTEXT DevContext, 
    _In_ PBAR_GRAPH_STATE BarGraphState
    )
/*++

Routine Description

    This routine sets the state of the bar graph on the board

Arguments:

    DevContext - One of our device extensions

    BarGraphState - Struct that describes the bar graph's desired state

Return Value:

    NT status value

--*/
{
    NTSTATUS status;
    WDF_USB_CONTROL_SETUP_PACKET    controlSetupPacket;
    WDF_REQUEST_SEND_OPTIONS        sendOptions;
    WDF_MEMORY_DESCRIPTOR memDesc;
    ULONG    bytesTransferred;

    PAGED_CODE();

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> SetBarGraphState\n");

    WDF_REQUEST_SEND_OPTIONS_INIT(
                                  &sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT
                                  );

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(
                                         &sendOptions,
                                         DEFAULT_CONTROL_TRANSFER_TIMEOUT
                                         );

    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestHostToDevice,
                                        BmRequestToDevice,
                                        USBFX2LK_SET_BARGRAPH_DISPLAY, // Request
                                        0, // Value
                                        0); // Index

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc,
                                                BarGraphState,
                                                sizeof(BAR_GRAPH_STATE));

    status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                        DevContext->UsbDevice,
                                        NULL, // Optional WDFREQUEST
                                        &sendOptions,
                                        &controlSetupPacket,
                                        &memDesc,
                                        &bytesTransferred);

    if(!NT_SUCCESS(status)) {

        TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL,
                        "SetBarGraphState: Failed - 0x%x \n", status);

    } else {

        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL,
            "SetBarGraphState: LED mask is 0x%x\n", BarGraphState->BarsAsUChar);
    }

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- SetBarGraphState\n");

    return status;

}
Exemple #28
0
NTSTATUS 
GetDevInfoData(
    __in  PFILTER_EXTENSION filterExt,
    __in  ULONG             DevInfoLen,
    __out BYTE*             pDevInfoData,
    __out size_t*           bytesRead
    )
/*++

Routine Description

    This routine gets the data of the device

Arguments:

    pDevInfoLen - One of our device extensions

Return Value:

    NT status value

--*/
{
    NTSTATUS status;

    WDF_USB_CONTROL_SETUP_PACKET    controlSetupPacket;
    WDF_REQUEST_SEND_OPTIONS        sendOptions;
    WDF_MEMORY_DESCRIPTOR           memDesc;
	ULONG                           bytesTransferred;

    PAGED_CODE();

    WDF_REQUEST_SEND_OPTIONS_INIT(
                                  &sendOptions,
                                  WDF_REQUEST_SEND_OPTION_TIMEOUT
                                  );

    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(
                                         &sendOptions,
                                         WDF_REL_TIMEOUT_IN_SEC(5)
                                         );

    WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
                                        BmRequestDeviceToHost,
                                        BmRequestToDevice,
                                        USBFX2LK_READ_DEVINFO_DATA, // Request
                                        0, // Value
                                        0); // Index


    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc,
                                      pDevInfoData,
                                      DevInfoLen);

    status = WdfUsbTargetDeviceSendControlTransferSynchronously(
                                        filterExt->UsbDevice,
                                        WDF_NO_HANDLE, // Optional WDFREQUEST
                                        &sendOptions,
                                        &controlSetupPacket,
                                        &memDesc,
                                        &bytesTransferred);

    if(!NT_SUCCESS(status)) {

		KdPrint( ("GetDevInfoData: Failed -  0x%x \n", status));
		*bytesRead = 0;

    } else {

		KdPrint( ("GetDevInfoData: transferred bytes %d \n", bytesTransferred ));
		*bytesRead = (size_t)bytesTransferred;		
    }

    return status;
}
NTSTATUS
Acpi_EvaluateUcsiDsm (
    _In_ PACPI_CONTEXT AcpiCtx,
    _In_ ULONG FunctionIndex,
    _Outptr_opt_ PACPI_EVAL_OUTPUT_BUFFER* Output
    )
/*++

    N.B. Caller is expected to free the Output buffer.

--*/
{
    NTSTATUS status;
    WDFDEVICE device;
    WDFMEMORY inputMemory;
    WDF_MEMORY_DESCRIPTOR inputMemDesc;
    PACPI_EVAL_INPUT_BUFFER_COMPLEX inputBuffer;
    size_t inputBufferSize;
    size_t inputArgumentBufferSize;
    PACPI_METHOD_ARGUMENT argument;
    WDF_MEMORY_DESCRIPTOR outputMemDesc;
    PACPI_EVAL_OUTPUT_BUFFER outputBuffer;
    size_t outputBufferSize;
    size_t outputArgumentBufferSize;
    WDF_OBJECT_ATTRIBUTES attributes;
    WDF_REQUEST_SEND_OPTIONS sendOptions;

    PAGED_CODE();

    TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI);

    device = Context_GetWdfDevice(AcpiCtx);
    inputMemory = WDF_NO_HANDLE;
    outputBuffer = nullptr;

    inputArgumentBufferSize =
        ACPI_METHOD_ARGUMENT_LENGTH(sizeof(GUID)) +
        ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) +
        ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) +
        ACPI_METHOD_ARGUMENT_LENGTH(0);

    inputBufferSize =
        FIELD_OFFSET(ACPI_EVAL_INPUT_BUFFER_COMPLEX, Argument) +
        inputArgumentBufferSize;

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = device;

    status = WdfMemoryCreate(&attributes,
                             NonPagedPoolNx,
                             0,
                             inputBufferSize,
                             &inputMemory,
                             (PVOID*) &inputBuffer);

    if (!NT_SUCCESS(status))
    {
        TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate failed for %Iu bytes - %!STATUS!", device, inputBufferSize, status);
        goto Exit;
    }

    RtlZeroMemory(inputBuffer, inputBufferSize);

    inputBuffer->Signature = ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE;
    inputBuffer->Size = (ULONG) inputArgumentBufferSize;
    inputBuffer->ArgumentCount = 4;
    inputBuffer->MethodNameAsUlong = (ULONG) 'MSD_';

    argument = &(inputBuffer->Argument[0]);
    ACPI_METHOD_SET_ARGUMENT_BUFFER(argument,
                                    &GUID_UCSI_DSM,
                                    sizeof(GUID_UCSI_DSM));

    argument = ACPI_METHOD_NEXT_ARGUMENT(argument);
    ACPI_METHOD_SET_ARGUMENT_INTEGER(argument, UCSI_DSM_REVISION);

    argument = ACPI_METHOD_NEXT_ARGUMENT(argument);
    ACPI_METHOD_SET_ARGUMENT_INTEGER(argument, FunctionIndex);

    argument = ACPI_METHOD_NEXT_ARGUMENT(argument);
    argument->Type = ACPI_METHOD_ARGUMENT_PACKAGE_EX;
    argument->DataLength = 0;

    outputArgumentBufferSize = ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG));
    outputBufferSize =
        FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) +
        outputArgumentBufferSize;

    outputBuffer = (PACPI_EVAL_OUTPUT_BUFFER) ExAllocatePoolWithTag(NonPagedPoolNx,
                                                                    outputBufferSize,
                                                                    TAG_UCSI);

    if (outputBuffer == nullptr)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ExAllocatePoolWithTag failed for %Iu bytes", device, outputBufferSize);
        goto Exit;
    }

    RtlZeroMemory(outputBuffer, outputBufferSize);

    WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&inputMemDesc, inputMemory, NULL);
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputMemDesc, outputBuffer, (ULONG) outputBufferSize);

    WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS);
    WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions,
                                         WDF_REL_TIMEOUT_IN_MS(UCSI_DSM_EXECUTION_TIMEOUT_IN_MS));

    status = WdfIoTargetSendInternalIoctlSynchronously(
                 WdfDeviceGetIoTarget(device),
                 NULL,
                 IOCTL_ACPI_EVAL_METHOD,
                 &inputMemDesc,
                 &outputMemDesc,
                 &sendOptions,
                 NULL);

    if (!NT_SUCCESS(status))
    {
        TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] IOCTL_ACPI_EVAL_METHOD for _DSM failed - %!STATUS!", device, status);
        goto Exit;
    }

    if (outputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE)
    {
        TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI_EVAL_OUTPUT_BUFFER signature is incorrect", device);
        status = STATUS_ACPI_INVALID_DATA;
        goto Exit;
    }

Exit:

    if (inputMemory != WDF_NO_HANDLE)
    {
        WdfObjectDelete(inputMemory);
    }

    if (!NT_SUCCESS(status) || (Output == nullptr))
    {
        if (outputBuffer)
        {
            ExFreePoolWithTag(outputBuffer, TAG_UCSI);
        }
    }
    else
    {
        *Output = outputBuffer;
    }

    TRACE_FUNC_EXIT(TRACE_FLAG_ACPI);

    return status;
}