Exemplo n.º 1
0
NTSTATUS
LoopbackDeviceCreateIoQueue(_In_ WDFDEVICE device)
{
    TraceEntry();
    
    NTSTATUS status = STATUS_SUCCESS;
    WDF_IO_QUEUE_CONFIG config;

    //
    // Register I/O callbacks to tell the framework that you are interested
    // in handling read and write requests.
    //
    // A default queue is where requests are delivered by the framework 
    // by default unless specific request handlers are configured using 
    // WdfDeviceConfigureRequestDispatching.
    //
    // WdfIoQueueDispatchSequential means that the queue is setup to dispatch 
    // no more than one WDFREQUEST at a time, so driver does not need to
    // protect data that could be accessed by the queue's callbacks concurrently
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&config, WdfIoQueueDispatchSequential);
    config.PowerManaged = WdfTrue;
    config.EvtIoWrite = LoopbackEvtIoWrite;
    config.EvtIoRead = LoopbackEvtIoRead;
    config.EvtIoDeviceControl = LoopbackEvtIoDeviceControl;

    status = WdfIoQueueCreate(
        device,
        &config,
        WDF_NO_OBJECT_ATTRIBUTES,
        nullptr);

    TraceStatusAndReturn(status);
}
Exemplo n.º 2
0
VOID
DevicePerformSoftReset (
    _In_ WDFDEVICE Device
    )
/*++

Routine Description:

    This functions performs soft reset of the controller and completes
    any initialization that needs to be done afterwards.

Arguments:

    Device - Wdf FDO device object representing the controller

--*/
{

    TraceEntry();

    UNREFERENCED_PARAMETER(Device);

    //
    // #### TODO: Insert code that performs a controller soft reset ####
    //

    TraceExit();
}
Exemplo n.º 3
0
VOID
HandleUsbDisconnect (
    WDFDEVICE WdfDevice
    )
/*++

Routine Description:

    Handles a disconnect event from the controller.

Arguments:

    WdfDevice - WDFDEVICE object representing the controller.

--*/
{
    TraceEntry();

    UNREFERENCED_PARAMETER(WdfDevice);

    //
    // #### TODO: Add any code needed to configure controller after disconnect event ####
    //

    TraceExit();
}
Exemplo n.º 4
0
VOID
UfxDevice_EvtCleanupCallback (
    _In_ WDFOBJECT   UfxDevice
    )
/*++

Routine Description:

    EvtCleanupCallback handler for the UFXDEVICE object.

Arguments:

    UfxDevice - Wdf object representing the UFXDEVICE

--*/
{
    PUFXDEVICE_CONTEXT DeviceContext = NULL;
    PCONTROLLER_CONTEXT ControllerContext = NULL;

    TraceEntry();

    DeviceContext = UfxDeviceGetContext(UfxDevice);
    ControllerContext = DeviceGetControllerContext(DeviceContext->FdoWdfDevice);

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

Routine Description:

    EvtIoDeviceControl handler for the default Queue

Arguments:

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

    Request - Handle to a framework request object.

    OutputBufferLength - Size of the output buffer in bytes

    InputBufferLength - Size of the input buffer in bytes

    IoControlCode - I/O control code.

--*/
{
    WDFDEVICE WdfDevice;
    PCONTROLLER_CONTEXT ControllerContext;
    BOOLEAN HandledbyUfx;   

    TraceEntry();

    TraceVerbose("Queue 0x%p, Request 0x%p, OutputBufferLength %d, "
                  "InputBufferLength %d, IoControlCode %d",
                  Queue, Request, (int) OutputBufferLength, 
                  (int) InputBufferLength, IoControlCode);
    
    WdfDevice = WdfIoQueueGetDevice(Queue);
    ControllerContext = DeviceGetControllerContext(WdfDevice);

    HandledbyUfx = UfxDeviceIoControl(
                        ControllerContext->UfxDevice,
                        Request,
                        OutputBufferLength,
                        InputBufferLength,
                        IoControlCode);

    if (!HandledbyUfx) {
        TraceError("Recieved an unsupported IOCTL");
        WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);
    }

    TraceExit();
}
Exemplo n.º 6
0
BOOLEAN 
DeviceInterrupt_EvtAttachDetachInterruptIsr (
    _In_ WDFINTERRUPT Interrupt,
    _In_ ULONG MessageID
    )
/*++

Routine Description:

    'EvtInterruptIsr' handler for the attach/detach interrupt object.
    http://msdn.microsoft.com/en-us/library/windows/hardware/ff541735(v=vs.85).aspx

Arguments:

    Interrupt - Associated interrupt object.

    MessageID - Message IDs for MSI

Return Value:

    BOOLEAN

--*/
{
    PCONTROLLER_CONTEXT ControllerContext;

    UNREFERENCED_PARAMETER(MessageID);

    TraceEntry();

    ControllerContext = DeviceGetControllerContext(WdfInterruptGetDevice(Interrupt));
    
    WdfInterruptAcquireLock(ControllerContext->DeviceInterrupt);

    //
    // This is an ActiveBoth interrupt used for attach/detach.  State is determined
    // by counting interrupts.  Previous state was attached, so this is a detach.
    //
    if (!ControllerContext->Attached) {
        ControllerContext->Attached = TRUE;
        ControllerContext->GotAttachOrDetach = TRUE;

        (void) WdfInterruptQueueDpcForIsr(Interrupt);
    } else  {
        ControllerContext->Attached = FALSE;
        ControllerContext->GotAttachOrDetach = TRUE;
        (void) WdfInterruptQueueDpcForIsr(Interrupt);
    }
        
    WdfInterruptReleaseLock(ControllerContext->DeviceInterrupt);
        
    TraceExit();
    return TRUE;
}
Exemplo n.º 7
0
VOID
LoopbackEvtIoRead(
    _In_ WDFQUEUE   queue,
    _In_ WDFREQUEST request,
    _In_ size_t     length
    )
{
    TraceEntry();

    ForwardRequestToIoTarget(queue, request, length);
}
Exemplo n.º 8
0
VOID
UfxDevice_EvtDeviceSuperSpeedPowerFeature (
    _In_ UFXDEVICE Device,
    _In_ USHORT Feature,
    _In_ BOOLEAN Set
    )
/*++

Routine Description:

    EvtDeviceSuperSpeedPowerFeature handler for the UFXDEVICE object.
    
    Handles a set or clear U1/U2 request from the host.  

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

    Feature - Indicates the feature being set or cleared.  Either U1 or U2 enable.

    Set - Indicates if the feature should be set or cleared
    
--*/
{
    TraceEntry();

    if (Feature == USB_FEATURE_U1_ENABLE) {
        if (Set == TRUE) {
            //
            // #### TODO: Insert code to initiate U1  ####
            //
        } else {
            //
            // #### TODO: Insert code to exit U1 ####
            //
        }
    } else if (Feature == USB_FEATURE_U2_ENABLE) {
        if (Set == TRUE) {
            //
            // #### TODO: Insert code to initiate U2 ####
            //
        } else {
            //
            // #### TODO: Insert code to exit U2 ####
            //
        }
    } else {
        NT_ASSERT(FALSE);
    }

    UfxDeviceEventComplete(Device, STATUS_SUCCESS);
    TraceExit();
}
Exemplo n.º 9
0
VOID
HandleUsbConnect (
    WDFDEVICE WdfDevice
    )
/*++

Routine Description:

    Handles a connect event from the controller.

Arguments:

    WDfDevice - WDFDEVICE object representing the controller.

--*/
{
    PCONTROLLER_CONTEXT ControllerContext;
    USB_DEVICE_SPEED DeviceSpeed;

    TraceEntry();

    ControllerContext = DeviceGetControllerContext(WdfDevice);

    //
    // Read the device speed.
    //

    //
    // #### TODO: Add code to read device speed from the controller ####
    //
    
    // Sample will assume SuperSpeed operation for illustration purposes
    DeviceSpeed = UsbSuperSpeed;
    
    //
    // #### TODO: Add any code needed to configure the controller after connect has occurred ####
    //


    ControllerContext->Speed = DeviceSpeed;
    TraceInformation("Connected Speed is %d!", DeviceSpeed);

    //
    // Notify UFX about reset, which will take care of updating 
    // Max Packet Size for EP0 by calling descriptor update.
    //
    UfxDeviceNotifyReset(ControllerContext->UfxDevice, DeviceSpeed);

    ControllerContext->Connect = TRUE;

    TraceExit();
}
Exemplo n.º 10
0
NTSTATUS
DefaultQueueCreate(
    _In_ WDFDEVICE Device
    )
/*++

Routine Description:

     Creates and configures the default IO Queue for the device.

Arguments:

    Device - Handle to a framework device object.

Return Value:

    Appropriate NTSTATUS message

--*/
{
    NTSTATUS Status;
    WDF_IO_QUEUE_CONFIG QueueConfig;
    
    TraceEntry();

    PAGED_CODE();
    
    //
    // Create the default queue
    //
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
                                    &QueueConfig,
                                    WdfIoQueueDispatchParallel
                                    );

    QueueConfig.PowerManaged = WdfTrue;
    QueueConfig.EvtIoDeviceControl = DefaultQueue_EvtIoDeviceControl;
    QueueConfig.EvtIoInternalDeviceControl = DefaultQueue_EvtIoInternalDeviceControl;

    Status = WdfIoQueueCreate(
                             Device,
                             &QueueConfig,
                             WDF_NO_OBJECT_ATTRIBUTES,
                             NULL);

    CHK_NT_MSG(Status, "WdfIoQueueCreate failed");

End:

    TraceExit();
    return Status;
}
Exemplo n.º 11
0
VOID
UfxDeviceSetRunStop (
    _In_ UFXDEVICE UfxDevice,
    _In_ BOOLEAN Set
    )
/*++

Routine Description:

    Function that sets or clears the run/stop state on the controller.  Setting the
    run state will initiate a connect to the host.

Arguments:

    UfxDevice - Wdf object representing the UFXDEVICE

    Set - TRUE if setting the run state, FALSE if clearing the run state.

--*/
{
    PCONTROLLER_CONTEXT ControllerContext;
    PUFXDEVICE_CONTEXT DeviceContext;
    BOOLEAN EventComplete;


    TraceEntry();

    DeviceContext = UfxDeviceGetContext(UfxDevice);
    ControllerContext = DeviceGetControllerContext(DeviceContext->FdoWdfDevice);

    EventComplete = TRUE;

    WdfSpinLockAcquire(ControllerContext->DpcLock);

    if (Set) {
        //
        // #### TODO: Insert code to set the run state on the controller ####
        //
    } else {
        //
        // #### TODO: Insert code to clear the run state on the controller ####
        //
    }

    WdfSpinLockRelease(ControllerContext->DpcLock);

    if (EventComplete) {
        UfxDeviceEventComplete(UfxDevice, STATUS_SUCCESS);
    }

    TraceExit();
}
Exemplo n.º 12
0
VOID
UfxDevice_EvtDeviceRemoteWakeupSignal (
    _In_ UFXDEVICE UfxDevice
    )
/*++
Routine Description:

    Signals Remote Wakeup to the Host by issuing a link state change command.
    It acquires and releases the power reference to ensure a valid power state
    before accessing the device.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

--*/
{
    NTSTATUS Status;
    PUFXDEVICE_CONTEXT DeviceContext;

    PAGED_CODE();

    TraceEntry();

    DeviceContext = UfxDeviceGetContext(UfxDevice);

    //
    // Stop Idle to ensure the device is in working state
    //
    Status = WdfDeviceStopIdle(DeviceContext->FdoWdfDevice, TRUE);
    if (!NT_SUCCESS(Status)) {
        TraceError("Failed to stop idle %!STATUS!", Status);
        goto End;
    }

    //
    // Issue a Link State Change Request.
    //

    //
    // #### TODO: Insert code to issue a link state change on the controller ####
    //

    WdfDeviceResumeIdle(DeviceContext->FdoWdfDevice);

End:
    UfxDeviceEventComplete(UfxDevice, Status);
    TraceExit();
}
Exemplo n.º 13
0
NTSTATUS
OnEvtDeviceReleaseHardware (
  _In_ WDFDEVICE Device,
  _In_ WDFCMRESLIST ResourcesTranslated
    )
/*++

Routine Description:

    EvtDeviceReleaseHardware callback handler for the controller FDO.
    It expects Register memory and two interrupts - Device and Wake.

Arguments:

    Device - WDFDEVICE object representing the controller.

    ResourcesTranslated - Translated resources available for the controller.

Return Value:

    Appropriate NTSTATUS value

--*/
{
    PREGISTERS_CONTEXT RegistersContext;
    PCONTROLLER_CONTEXT ControllerContext;

    TraceEntry();

    PAGED_CODE();

    UNREFERENCED_PARAMETER(ResourcesTranslated);

    ControllerContext = DeviceGetControllerContext(Device);
    ControllerContext->DeviceInterrupt = NULL;
    ControllerContext->AttachDetachInterrupt = NULL;
   
    RegistersContext = DeviceGetRegistersContext(Device);
    if ((RegistersContext == NULL) || (RegistersContext->RegisterBase == NULL)) {
        goto End;
    }

    MmUnmapIoSpace(RegistersContext->RegisterBase, RegistersContext->RegistersLength);
    RtlZeroMemory(RegistersContext, sizeof(*RegistersContext));

End:
    TraceExit();
    return STATUS_SUCCESS;
}
Exemplo n.º 14
0
NTSTATUS
OnEvtDeviceD0Entry (
  _In_ WDFDEVICE Device,
  _In_ WDF_POWER_DEVICE_STATE PreviousState
)
/*++

Routine Description:

    Called by the framework after entering D0 state.

Arguments:

    Device - WDFDEVICE framework handle to the bus FDO.

    PreviousState - The WDF_POWER_DEVICE_STATE from which the stack is
        making this transition.

Return Value:

    Returns STATUS_SUCCESS or an appropriate NTSTATUS code otherwise.

--*/
{
    PCONTROLLER_CONTEXT ControllerContext;

    TraceEntry();

    ControllerContext = DeviceGetControllerContext(Device);

    if (PreviousState > WdfPowerDeviceD1) { 
        DevicePerformSoftReset(Device);

        WdfWaitLockAcquire(ControllerContext->InitializeDefaultEndpointLock, NULL);
        ControllerContext->InitializeDefaultEndpoint = TRUE;
        WdfWaitLockRelease(ControllerContext->InitializeDefaultEndpointLock);
    }

    if (PreviousState == WdfPowerDeviceD3Final) {
        //
        // Notify UFX that HW is now ready
        //
        UfxDeviceNotifyHardwareReady(ControllerContext->UfxDevice);
    }

    TraceExit();
    return STATUS_SUCCESS;
}
Exemplo n.º 15
0
VOID
UfxDevice_Reset (
    _In_ UFXDEVICE Device
    )
/*++

Routine Description:

    Cancels all transfers and disables non-zero endpoints in
    response to USB reset.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

--*/
{
    PUFXDEVICE_CONTEXT DeviceContext;
    PREGISTERS_CONTEXT RegistersContext;
    ULONG EpIndex;

    TraceEntry();

    DeviceContext = UfxDeviceGetContext(Device);
    RegistersContext = DeviceGetRegistersContext(DeviceContext->FdoWdfDevice);

    //
    // Get EP0 back to setup stage.
    //
    TransferReset(WdfCollectionGetFirstItem(DeviceContext->Endpoints));

    //
    // Disable all non-default endpoints
    //

    // 
    // #### TODO: Insert code to disable non-default endpoints ####
    //

    //
    // End any transfers on non-default endpoints.
    //
    for (EpIndex = 1; EpIndex < WdfCollectionGetCount(DeviceContext->Endpoints); EpIndex++) {
        TransferReset(WdfCollectionGetItem(DeviceContext->Endpoints, EpIndex));
    }

    TraceExit();
}
Exemplo n.º 16
0
BOOLEAN 
DeviceInterrupt_EvtInterruptIsr(
    _In_ WDFINTERRUPT Interrupt,
    _In_ ULONG MessageID
    )
/*++

Routine Description:

    'EvtInterruptIsr' handler for the device interrupt object.
    http://msdn.microsoft.com/en-us/library/windows/hardware/ff541735(v=vs.85).aspx

Arguments:

    Interrupt - Associated interrupt object.

    MessageID - Message IDs for MSI

Return Value:

    Appropriate NTSTATUS value

--*/
{
    BOOLEAN PendingEvents;

    TraceEntry();

    UNREFERENCED_PARAMETER(MessageID);

    //
    // #### TODO: Determine if controller has pending events. ####
    // 
    
    // Sample will assume there is always a pending event for illustration purposes.
    PendingEvents = TRUE;

    if (PendingEvents) {
        //    
        // Enqueue the DPC to handle the events.
        //
        WdfInterruptQueueDpcForIsr(Interrupt);
    }

    TraceExit();
    return TRUE;
}
Exemplo n.º 17
0
VOID
DeviceInitializeDefaultEndpoint (
    _In_ WDFDEVICE Device
    )
/*++

Routine Description:

    This function initializes the default control endpoint

Arguments:

    Device - Wdf FDO device object representing the controller

--*/
{
    UFXENDPOINT Endpoint;
    PUFXDEVICE_CONTEXT DeviceContext;
    PCONTROLLER_CONTEXT ControllerContext;
    NTSTATUS Status;

    TraceEntry();

    ControllerContext = DeviceGetControllerContext(Device);
    DeviceContext = UfxDeviceGetContext(ControllerContext->UfxDevice);

    if (DeviceContext->PhysicalEndpointToUfxEndpoint[0] != NULL) {
        Endpoint = DeviceContext->PhysicalEndpointToUfxEndpoint[0];

        //
        // Re-initialize endpoint 0
        //
        TransferDestroy(Endpoint);
        
        Status = TransferInitialize(Endpoint);
        LOG_NT_MSG(Status, "Failed to initialize default endpoint");

        UfxEndpointConfigureHardware(Endpoint, FALSE);
        TransferStart(Endpoint);

    } else {
        NT_ASSERT(FALSE);
    }

    TraceExit();
}
Exemplo n.º 18
0
VOID
UfxDevice_EvtDeviceDefaultEndpointAdd (
    _In_ UFXDEVICE UfxDevice,
    _In_ USHORT MaxPacketSize,
    _Inout_ PUFXENDPOINT_INIT EndpointInit
    )
/*++

Routine Description:

    EvtDeviceDefaultEndpointAdd handler for the UFXDEVICE object.
    Creates UFXENDPOINT object corresponding to the default endpoint of the
    device.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

    MaxPacketSize - Max packet size of the device's default endpoint.

    EndpointInit - Pointer to the Opaque UFXENDPOINT_INIT object

--*/
{
    NTSTATUS Status;
    USB_ENDPOINT_DESCRIPTOR Descriptor;

    PAGED_CODE();

    TraceEntry();

    Descriptor.bDescriptorType = USB_ENDPOINT_DESCRIPTOR_TYPE;
    Descriptor.bEndpointAddress = 0;
    Descriptor.bInterval = 0;
    Descriptor.bLength = sizeof(USB_ENDPOINT_DESCRIPTOR);
    Descriptor.bmAttributes = USB_ENDPOINT_TYPE_CONTROL;
    Descriptor.wMaxPacketSize = MaxPacketSize;

    Status = UfxEndpointAdd(UfxDevice, &Descriptor, EndpointInit);
    CHK_NT_MSG(Status, "Failed to create default endpoint!");

End:
    UfxDeviceEventComplete(UfxDevice, Status);
    TraceExit();
}
Exemplo n.º 19
0
VOID
HandleUSBLinkStateChange (
    WDFDEVICE WdfDevice
    )
/*++

Routine Description:

    Handles a link change event from the controller.

Arguments:

    WdfDevice - WDFDEVICE object representing the controller.

--*/
{
    PCONTROLLER_CONTEXT ControllerContext;
    ULONG UsbLinkEvent;

    TraceEntry();

    ControllerContext = DeviceGetControllerContext(WdfDevice);
    
    //
    // #### TODO: Add code to read link state from controller ####
    // 
    // For sample purposes use U0.
    UsbLinkEvent = USB_LINK_STATE_U0;

    if (UsbLinkEvent == USB_LINK_STATE_U0) { 

        if(ControllerContext->Suspended) {
            ControllerContext->Suspended = FALSE;
            UfxDeviceNotifyResume(ControllerContext->UfxDevice);    
        }

        ControllerContext->RemoteWakeupRequested = FALSE;

    } else {
        TraceVerbose("Ignoring link state change event: 0X%X", UsbLinkEvent);
    }

    TraceExit();
}
Exemplo n.º 20
0
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);
}
Exemplo n.º 21
0
NTSTATUS
UfxDevice_EvtDeviceEndpointAdd (
    _In_ UFXDEVICE UfxDevice,
    _In_ const PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor,
    _Inout_ PUFXENDPOINT_INIT EndpointInit
    )
/*++

Routine Description:

    EvtDeviceEndpointAdd handler for the UFXDEVICE object.
    Creates UFXENDPOINT object corresponding to the newly reported endpoint.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

    EndpointDescriptor - Cosntant Pointer to Endpoint descriptor for the
        newly reported endpoint.

    EndpointInit - Pointer to the Opaque UFXENDPOINT_INIT object

Return Value:

    STATUS_SUCCESS on success, or an appropirate NTSTATUS message on failure.

--*/
{
    NTSTATUS Status;

    TraceEntry();

    Status = UfxEndpointAdd(UfxDevice, EndpointDescriptor, EndpointInit);
    CHK_NT_MSG(Status, "Failed to create endpoint");

End:

    TraceExit();
    return Status;
}
Exemplo n.º 22
0
VOID
LoopbackEvtIoDeviceControl(
    _In_ WDFQUEUE   Queue,
    _In_ WDFREQUEST Request,
    _In_ size_t     OutputBufferLength,
    _In_ size_t     InputBufferLength,
    _In_ ULONG      IoControlCode)
{
    UNREFERENCED_PARAMETER((OutputBufferLength, InputBufferLength));

    TraceEntry();

    NTSTATUS status = STATUS_SUCCESS;

    if (IoControlCode != LOOPBACK_IOCTL_ALTER_MAX_LENGTH || InputBufferLength != 4)
    {
        status = STATUS_UNSUCCESSFUL;

        goto Cleanup;
    }

    PUINT32 buffer;
    status = WdfRequestRetrieveInputBuffer(Request, 4, (PVOID*)&buffer, nullptr);

    if (!NT_SUCCESS(status))
    {
        TraceError("%!FUNC! - Unable to read IOCTL input buffer. Status - %!STATUS!", status);

        goto Cleanup;
    }

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

    context->MaxLengthInBytesForRWTransfers = *buffer;

Cleanup:

    WdfRequestComplete(Request, status);
}
Exemplo n.º 23
0
VOID
UfxDevice_EvtDevicePortChange (
    _In_
        UFXDEVICE UfxDevice,
    _In_
        USBFN_PORT_TYPE NewPort
    )
/*++

Routine Description:

    EvtDevicePortChange handler for the UFXDEVICE object.
    Caches the new port type, and stops or resumes idle as needed.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

    NewPort - New port type

--*/
{
    NTSTATUS Status;
    PUFXDEVICE_CONTEXT Context;

    PAGED_CODE();

    TraceEntry();

    Context = UfxDeviceGetContext(UfxDevice);

    TraceInformation("New PORT: %d", NewPort);

    Status = UfxDeviceStopOrResumeIdle(UfxDevice, Context->UsbState, NewPort);
    LOG_NT_MSG(Status, "Failed to stop or resume idle");

    UfxDeviceEventComplete(UfxDevice, STATUS_SUCCESS);
    TraceExit();
}
Exemplo n.º 24
0
VOID
UfxDevice_EvtDeviceHostConnect (
    _In_ UFXDEVICE UfxDevice
    )
/*++

Routine Description:

    EvtDeviceHostConnect callback handler for UFXDEVICE object.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

--*/
{
    TraceEntry();

    UfxDeviceSetRunStop(UfxDevice, TRUE);

    TraceExit();
}
Exemplo n.º 25
0
VOID
UfxDevice_EvtDeviceTestModeSet (
    _In_ UFXDEVICE UfxDevice,
    _In_ ULONG TestMode
    )
/*++

Routine Description:

    EvtDeviceTestModeSet handler for the UFXDEVICE object.
    
    Handles a set test mode request from the host.  Places the controller into 
    the specified test mode.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

    TestMode - Test mode value.  See Section 7.1.20 of the USB 2.0 specification for definitions of 
               each test mode.

--*/
{
    NTSTATUS Status;

    UNREFERENCED_PARAMETER(TestMode);

    TraceEntry();

    //
    // #### TODO: Insert code to put the controller into the specified test mode ####
    //

    Status = STATUS_SUCCESS;

    UfxDeviceEventComplete(UfxDevice, Status);
    TraceExit();
}
Exemplo n.º 26
0
VOID
HandleUsbReset (
    WDFDEVICE WdfDevice
    )
/*++

Routine Description:

    Handles a reset event notification from the controller.

Arguments:

    WdfDevice - WDFDEVICE object representing the controller.

--*/
{
    PCONTROLLER_CONTEXT ControllerContext;

    TraceEntry();

    ControllerContext = DeviceGetControllerContext(WdfDevice);

    UfxDevice_Reset(ControllerContext->UfxDevice);
            
    ControllerContext->RemoteWakeupRequested = FALSE;

    //
    // Update the controller to set device address to 0
    //

    //
    // #### TODO: Add code to set the USB device address to 0 on the controller ####
    //

    TraceExit();
}
Exemplo n.º 27
0
VOID
UfxDevice_EvtDeviceAddressed (
    _In_ UFXDEVICE UfxDevice,
    _In_ USHORT DeviceAddress
    )
/*++

Routine Description:

    EvtDeviceAddressed handler for the UFXDEVICE object.
    Sets the Address indicated by 'DeviceAddress' on the controller.

Arguments:

    UfxDevice - UFXDEVICE object representing the device.

    DeviceAddress - USB Device Address, as determined by the UFX.

--*/
{
    UNREFERENCED_PARAMETER(DeviceAddress);

    TraceEntry();

    //
    // Set the device address on the controller
    //

    //
    // #### Insert code to set the device address on controller ####
    //
    
    UfxDeviceEventComplete(UfxDevice, STATUS_SUCCESS);

    TraceExit();
}
Exemplo n.º 28
0
VOID
HandleEndpointEvent (
    WDFDEVICE WdfDevice,
    ENDPOINT_EVENT EndpointEvent
    )
/*++

Routine Description:

    Function to dispatch endpoint events.

Arguments:

    WdfDevice - Wdf device object corresponding to the FDO

    EndpointEvent -  Endpoint specific event.

--*/
{
    UFXENDPOINT Endpoint;
    PCONTROLLER_CONTEXT ControllerContext;
    PUFXDEVICE_CONTEXT DeviceContext;

    TraceEntry();

    ControllerContext = DeviceGetControllerContext(WdfDevice);
    DeviceContext = UfxDeviceGetContext(ControllerContext->UfxDevice);

    //
    // #### TODO: Insert code to extract endpoint event and endpoint number ####
    // 
    
    // Sample will assume a transfer complete event on endpoint 1 for illustration purposes
    EndpointEvent = EndpointEventTransferComplete;
    
    Endpoint = DeviceContext->PhysicalEndpointToUfxEndpoint[1];

    switch (EndpointEvent) {

    case EndpointEventTransferComplete:
        TraceInformation("ENDPOINT EVENT: TransferComplete");
        TransferComplete(Endpoint);
        break;

    case EndpointEventStartTransferComplete:
        TraceInformation("ENDPOINT EVENT: Complete Start Transfer");
        TransferCommandStartComplete(Endpoint);
        break;

    case EndpointEventEndTransferComplete:
        TraceInformation("ENDPOINT EVENT: Complete End Transfer");
        TransferCommandEndComplete(Endpoint);
        break;
        
    case EndpointEventSetStall:
        TraceInformation("ENDPOINT EVENT: Command Complete Stall Set");
        TransferStallSetComplete(Endpoint);
        break;
           
    case EndpointEventClearStall:
        TraceInformation("ENDPOINT EVENT: Command Complete Stall Clear");
        TransferStallClearComplete(Endpoint);
        break;

    default:
        TraceError("Unexpected endpoint event!");
        NT_ASSERT(FALSE);
    }

    TraceExit();
}
Exemplo n.º 29
0
VOID
HandleDeviceEvent (
    WDFDEVICE WdfDevice,
    DEVICE_EVENT DeviceEvent
    )
/*++

Routine Description:

    Function to dispatch device events from the controller.

Arguments:

    WdfDevice - Wdf device object corresponding to the FDO

    DeviceEvent -  Device specific event.

--*/
{
    PCONTROLLER_CONTEXT ControllerContext;

    TraceEntry();

    ControllerContext = DeviceGetControllerContext(WdfDevice);

    switch (DeviceEvent) {

    case DeviceEventDisconnect:
        ControllerContext->Suspended = FALSE;
        HandleUsbDisconnect(WdfDevice);
        break;

    case DeviceEventUSBReset:
        ControllerContext->Suspended = FALSE;
        HandleUsbReset(WdfDevice);
        break;

    case DeviceEventConnect:
        HandleUsbConnect(WdfDevice);
        break;

    case DeviceEventUSBLinkStateChange:
        HandleUSBLinkStateChange(WdfDevice);
        break;

    case DeviceEventWakeUp:
        if (ControllerContext->Suspended) {
            ControllerContext->Suspended = FALSE;
            UfxDeviceNotifyResume(ControllerContext->UfxDevice);
        }
        break;

    case DeviceEventSuspend:
        if (!ControllerContext->Suspended) {
            ControllerContext->Suspended = TRUE;
            UfxDeviceNotifySuspend(ControllerContext->UfxDevice);
        }
        break;

    default:
        TraceError("Unknown device event raised by controller");
        NT_ASSERT(FALSE);
        break;
    }    

    TraceExit();
}
Exemplo n.º 30
0
NTSTATUS
UfxClientDeviceCreate(
    _In_ WDFDRIVER Driver,
    _In_ PWDFDEVICE_INIT DeviceInit
    )
/*++

Routine Description:

    Worker routine called to create a device and its software resources.

Arguments:

    Driver - WDF driver object

    DeviceInit - Pointer to an opaque init structure. Memory for this
                 structure will be freed by the framework when the WdfDeviceCreate
                 succeeds. So don't access the structure after that point.

Return Value:

    Appropriate NTSTATUS value

--*/
{
    WDF_OBJECT_ATTRIBUTES DeviceAttributes;
    WDFDEVICE WdfDevice;
    NTSTATUS Status;
    WDF_PNPPOWER_EVENT_CALLBACKS PnpCallbacks;
    WDF_DMA_ENABLER_CONFIG DmaConfig;
    PCONTROLLER_CONTEXT ControllerContext;

    PAGED_CODE();

    TraceEntry();

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&DeviceAttributes, CONTROLLER_CONTEXT);

    //
    // Do UFX-specific initialization
    //
    Status = UfxFdoInit(Driver, DeviceInit, &DeviceAttributes);
    CHK_NT_MSG(Status, "Failed UFX initialization");

    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&PnpCallbacks);
    PnpCallbacks.EvtDevicePrepareHardware = OnEvtDevicePrepareHardware;
    PnpCallbacks.EvtDeviceReleaseHardware = OnEvtDeviceReleaseHardware;
    PnpCallbacks.EvtDeviceD0Entry = OnEvtDeviceD0Entry;
    PnpCallbacks.EvtDeviceD0Exit = OnEvtDeviceD0Exit;
    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &PnpCallbacks);

    Status = WdfDeviceCreate(&DeviceInit, &DeviceAttributes, &WdfDevice);
    CHK_NT_MSG(Status, "Failed to create wdf device");

    ControllerContext = DeviceGetControllerContext(WdfDevice);

    KeInitializeEvent(&ControllerContext->DetachEvent,
                      NotificationEvent,
                      FALSE);

    WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&ControllerContext->IdleSettings, IdleCanWakeFromS0);
    ControllerContext->IdleSettings.IdleTimeoutType = SystemManagedIdleTimeoutWithHint;
    ControllerContext->IdleSettings.IdleTimeout = IDLE_TIMEOUT;
    ControllerContext->IdleSettings.DxState = PowerDeviceD3;

    Status = WdfDeviceAssignS0IdleSettings(WdfDevice, &ControllerContext->IdleSettings);
    LOG_NT_MSG(Status, "Failed to set S0 Idle Settings");

    //
    // Create and initialize device's default queue
    //
    Status = DefaultQueueCreate(WdfDevice);
    CHK_NT_MSG(Status, "Failed to intialize default queue");

    //
    // Set alignment required by controller
    //
    WdfDeviceSetAlignmentRequirement(WdfDevice, UFX_CLIENT_ALIGNMENT);

    //
    // Create and Initialize DMA Enabler object for the device.
    //
    WDF_DMA_ENABLER_CONFIG_INIT(
                        &DmaConfig,
                        WdfDmaProfileScatterGatherDuplex,
                        MAX_DMA_LENGTH);
    //
    // Version 3 is required to perform multiple
    // simultaneous transfers.
    //
    DmaConfig.WdmDmaVersionOverride = 3;

    Status = WdfDmaEnablerCreate(
                            WdfDevice,
                            &DmaConfig,
                            WDF_NO_OBJECT_ATTRIBUTES,
                            &ControllerContext->DmaEnabler);
    CHK_NT_MSG(Status, "Failed to create DMA enabler object");

    //
    // Create UFXDEVICE object
    //
    Status = UfxDevice_DeviceCreate(WdfDevice);
    CHK_NT_MSG(Status, "Failed to create UFX Device object");

    //
    // Create DPC Lock
    //
    Status = WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &ControllerContext->DpcLock);
    CHK_NT_MSG(Status, "Failed to create DPC lock");

    Status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &ControllerContext->InitializeDefaultEndpointLock);
    CHK_NT_MSG(Status, "Failed to create Ep0 init lock");

End:
    TraceExit();
    return Status;
}