Esempio n. 1
0
VOID
VIOSerialPortPnpNotifyWork(
    IN WDFWORKITEM  WorkItem
    )
{
    PRAWPDO_VIOSERIAL_PORT  pdoData = RawPdoSerialPortGetData(WorkItem);
    PVIOSERIAL_PORT         pport = pdoData->port;
    PTARGET_DEVICE_CUSTOM_NOTIFICATION  notification;
    ULONG                               requiredSize;
    NTSTATUS                            status;
    VIRTIO_PORT_STATUS_CHANGE           portStatus = {0};

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);
    portStatus.Version = 1;
    portStatus.Reason = pport->HostConnected;

    status = RtlULongAdd((sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION) - sizeof(UCHAR)),
                                 sizeof(VIRTIO_PORT_STATUS_CHANGE),
                                 &requiredSize);

    if (NT_SUCCESS(status))
    {
        notification = (PTARGET_DEVICE_CUSTOM_NOTIFICATION)
                       ExAllocatePoolWithTag(NonPagedPool,
                                 requiredSize,
                                 VIOSERIAL_DRIVER_MEMORY_TAG);

        if (notification != NULL)
        {
            RtlZeroMemory(notification, requiredSize);
            notification->Version = 1;
            notification->Size = (USHORT)(requiredSize);
            notification->FileObject = NULL;
            notification->NameBufferOffset = -1;
            notification->Event = GUID_VIOSERIAL_PORT_CHANGE_STATUS;
            RtlCopyMemory(notification->CustomDataBuffer, &portStatus, sizeof(VIRTIO_PORT_STATUS_CHANGE));
            if(WdfDeviceGetDevicePnpState(pport->Device) == WdfDevStatePnpStarted)
            {
               status = IoReportTargetDeviceChangeAsynchronous(
                                 WdfDeviceWdmGetPhysicalDevice(pport->Device),
                                 notification,
                                 NULL,
                                 NULL);
               if (!NT_SUCCESS(status))
               {
                    TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                                 "IoReportTargetDeviceChangeAsynchronous Failed! status = 0x%x\n", status);
               }
            }
            ExFreePoolWithTag(notification, VIOSERIAL_DRIVER_MEMORY_TAG);
        }
    }
    WdfObjectDelete(WorkItem);
    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__);
}
Esempio n. 2
0
__inline
VOID
MP_FREE_SEND_PACKET(
    IN  PFDO_DATA   FdoData,
    IN  PMP_TCB     pMpTcb,
    IN  NTSTATUS    Status
    )
/*++
Routine Description:

    Recycle a MP_TCB and complete the packet if necessary

    Assumption: This function is called with the Send SPINLOCK held.

Arguments:

    FdoData     Pointer to our FdoData
    pMpTcb      Pointer to MP_TCB

Return Value:

    None

--*/
{

    WDFREQUEST          request;
    WDFDMATRANSACTION   dmaTransaction;
    size_t              length;

    ASSERT(MP_TEST_FLAG(pMpTcb, fMP_TCB_IN_USE));

    dmaTransaction = pMpTcb->DmaTransaction;
    pMpTcb->DmaTransaction = NULL;

    MP_CLEAR_FLAGS(pMpTcb);

    FdoData->CurrSendHead = FdoData->CurrSendHead->Next;
    FdoData->nBusySend--;

    request = WdfDmaTransactionGetRequest(dmaTransaction);
    length  = WdfDmaTransactionGetBytesTransferred(dmaTransaction);

    WdfObjectDelete( dmaTransaction );

    if (request)
    {
        WdfSpinLockRelease(FdoData->SendLock);
        WdfRequestCompleteWithInformation(request, Status, length);
        FdoData->BytesTransmitted += length;

        WdfSpinLockAcquire(FdoData->SendLock);
    }
}
static VOID
XenVbd_StartRing(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 'start' down if we are resuming from a suspend */
  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.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_START;
    
    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);
  }
  
  FUNCTION_EXIT();
}
// Internal routine to perform simulator initialization
NTSTATUS
HardwareSimulator::InitializeInternal(
    _In_ WDFOBJECT SimulatorInstance)    // Instance of the WDF object for the simulator
{
    NTSTATUS Status = STATUS_SUCCESS;
    WDF_OBJECT_ATTRIBUTES TimerAttributes = {};
    WDF_TIMER_CONFIG TimerConfig = {};

    SENSOR_FunctionEnter();

    // Only initialize the simulator if it is in the "not initialized" state
    if (SimulatorState_NotInitialized == m_State)
    {
        // Create Lock
        Status = WdfWaitLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &m_Lock);
        if (!NT_SUCCESS(Status))
        {
            m_Lock = NULL;

            TraceError("CSTM %!FUNC! WdfWaitLockCreate failed %!STATUS!", Status);
            goto Exit;
        }

        // Create a timer object for simulation updates
        WDF_TIMER_CONFIG_INIT(&TimerConfig, HardwareSimulator::OnTimerExpire);
        WDF_OBJECT_ATTRIBUTES_INIT(&TimerAttributes);
        TimerAttributes.ParentObject = SimulatorInstance;
        TimerAttributes.ExecutionLevel = WdfExecutionLevelPassive;

        Status = WdfTimerCreate(&TimerConfig, &TimerAttributes, &m_Timer);
        if (!NT_SUCCESS(Status))
        {
            m_Timer = NULL;

            TraceError("CSTM %!FUNC! WdfTimerCreate failed %!STATUS!", Status);
            goto Exit;
        }

        // Set the simulator state to "initialized"
        m_State = SimulatorState_Initialized;
        m_SimulatorInstance = SimulatorInstance;
    }

Exit:
    if (!NT_SUCCESS(Status) && NULL != m_Lock)
    {
        WdfObjectDelete(m_Lock);
        m_Lock = NULL;
    }

    SENSOR_FunctionExit(Status);

    return Status;
}
Esempio n. 5
0
VOID
ToastMon_EvtIoTargetRemoveComplete(
    WDFIOTARGET IoTarget
)
/*++

Routine Description:

    Called when the Target device is removed ( either the target
    received IRP_MN_REMOVE_DEVICE or IRP_MN_SURPRISE_REMOVAL)

Arguments:

    IoTarget -

Return Value:


--*/
{
    PDEVICE_EXTENSION      deviceExtension;
    PTARGET_DEVICE_INFO    targetDeviceInfo = NULL;

    KdPrint((("Device Removal (remove complete) Notification\n")));

    PAGED_CODE();

    targetDeviceInfo = GetTargetDeviceInfo(IoTarget);
    deviceExtension = targetDeviceInfo->DeviceExtension;

    //
    // Stop the timer 
    //
    WdfTimerStop(targetDeviceInfo->TimerForPostingRequests, TRUE);

    //
    // Remove the target device from the collection.
    //
    WdfWaitLockAcquire(deviceExtension->TargetDeviceCollectionLock, NULL);

    WdfCollectionRemove(deviceExtension->TargetDeviceCollection, IoTarget);

    WdfWaitLockRelease(deviceExtension->TargetDeviceCollectionLock);

    //
    // Finally delete the target.
    //
    WdfObjectDelete(IoTarget);

    return;

}
Esempio n. 6
0
VOID
ToastMon_EvtIoTargetRemoveCanceled(
    WDFIOTARGET IoTarget
    )
/*++

Routine Description:

    Called when the Target device received IRP_MN_CANCEL_REMOVE.
    This happens if another app or driver talking to the target
    device doesn't close handle or veto query-remove notification.

Arguments:

    IoTarget -

Return Value:


--*/
{
    PTARGET_DEVICE_INFO         targetDeviceInfo = NULL;
    WDF_IO_TARGET_OPEN_PARAMS   openParams;
    NTSTATUS status;

    PAGED_CODE();

    KdPrint((("Device Removal (remove cancelled) Notification\n")));

    targetDeviceInfo = GetTargetDeviceInfo(IoTarget);

    //
    // Reopen the Target.
    //
    WDF_IO_TARGET_OPEN_PARAMS_INIT_REOPEN(&openParams);

    status = WdfIoTargetOpen(IoTarget, &openParams);

    if (!NT_SUCCESS(status)) {
        KdPrint(("WdfIoTargetOpen failed 0x%x\n", status));
        WdfObjectDelete(IoTarget);
        return;
    }

    //
    // Restart the timer.
    //
    WdfTimerStart(targetDeviceInfo->TimerForPostingRequests,
                                        WDF_REL_TIMEOUT_IN_SEC(1));

}
Esempio n. 7
0
VOID  
kmdf1394_AsyncReadCompletion (    
                              IN WDFREQUEST  Request,    
                              IN WDFIOTARGET  Target,    
                              IN PWDF_REQUEST_COMPLETION_PARAMS  Params,    
                              IN WDFCONTEXT  Context)
/*++

Routine Description:

    Async Read completion routine.

Arguments:

Arguments:

    Request - UNUSED

    Target - UNUSED

    Params - UNUSED
    
    Context - Pointer to a WDFMemory Object

Return Value:

    VOID
--*/
{
    PIRB pIrb = NULL;

    UNREFERENCED_PARAMETER (Request);
    UNREFERENCED_PARAMETER (Target);
    UNREFERENCED_PARAMETER (Params);

    Enter();

    ASSERT (Context);

    pIrb = (PIRB) WdfMemoryGetBuffer ((WDFMEMORY)Context, NULL);

    //
    // Just basic clean up here.
    //
    IoFreeMdl (pIrb->u.AsyncRead.Mdl);
    ExFreePoolWithTag (pIrb, POOLTAG_KMDF_VDEV);
    WdfObjectDelete ((WDFMEMORY) Context);

    Exit();
}
VOID
kmdf1394_SubmitIrpAsyncCompletion (
                                   IN WDFREQUEST  Request,    
                                   IN WDFIOTARGET  Target,    
                                   IN PWDF_REQUEST_COMPLETION_PARAMS  Params,    
                                   IN WDFCONTEXT  Context)
/*++

Routine Description:

    Asynchronous request completion routine

Arguments:

    Request - current request object

    Target - I/O Target object

    Params - WDF request Parameter structure
    
    Context - any additional objects the request may 
    need to clean up from the inital submission.

Return Value:

    NTSTATUS value
--*/
{
    // 
    // Here we'll free our memory object from the async request.
    //
    UNREFERENCED_PARAMETER (Target);
    UNREFERENCED_PARAMETER (Request);

    ASSERT (Context);

    
    if (!NT_SUCCESS(Params->IoStatus.Status))
    {
        TRACE(
            TL_ERROR, 
            ("Request %x Failed with status %x\n",
            Request,
            Params->IoStatus.Status));
    }
    

    WdfObjectDelete (Context);
}
void AndroidUsbPipeFileObject::ResetPipePassiveCallbackEntry(
    WDFWORKITEM wdf_work_item) {
  ASSERT_IRQL_PASSIVE();

  AndroidUsbWorkitemContext* context =
    GetAndroidUsbWorkitemContext(wdf_work_item);
  ASSERT((NULL != context) &&
         (AndroidUsbWdfObjectTypeWorkitem == context->object_type));
  if ((NULL == context) ||
      (AndroidUsbWdfObjectTypeWorkitem != context->object_type)) {
    WdfObjectDelete(wdf_work_item);
    return;
  }

  // In the sample they reset the device if pipe reset failed
  AndroidUsbDeviceObject* wdf_device_ext =
    context->pipe_file_ext->device_object();

  NTSTATUS status = context->pipe_file_ext->ResetPipe();
  if (!NT_SUCCESS(status))
    status = wdf_device_ext->ResetDevice();
  
  WdfObjectDelete(wdf_work_item);
}
Esempio n. 10
0
/** 
 * @brief deallocate callback item.
 *  Must be called with lock held.
 * *Note* this is called only to deal with error cases. The normal
 * callback function re-adds the work item to the collection.
 * 
 * @param[in] WorkItem allocated WorkItem to be freed.
 * 
 */
VOID
FreeWorkItem(
    IN WDFWORKITEM WorkItem)
{
    PUSB_FDO_WORK_ITEM_CONTEXT  context = WorkItemGetContext(WorkItem);
    NTSTATUS Status = WdfCollectionAdd(context->FdoContext->FreeWorkItems,
        WorkItem);

    if (!NT_SUCCESS(Status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            __FUNCTION__": Device %p WdfCollectionAdd error %x, deleting instead.\n",
            context->FdoContext->WdfDevice,
            Status);
        WdfObjectDelete(WorkItem);
    }
}
Esempio n. 11
0
static VOID UsbChief_ReadWriteWorkItem(IN WDFWORKITEM  WorkItem)
{
	PWORKITEM_CONTEXT pItemContext;
	NTSTATUS status;

	UsbChief_DbgPrint(DEBUG_RW, ("called\n"));

	pItemContext = GetWorkItemContext(WorkItem);

	status = UsbChief_ResetPipe(pItemContext->Pipe);
	if (!NT_SUCCESS(status)) {
		status = UsbChief_ResetDevice(pItemContext->Device);
		if(!NT_SUCCESS(status))
			UsbChief_DbgPrint(0, ("ResetDevice failed 0x%x\n", status));
	}
	WdfObjectDelete(WorkItem);
}
Esempio n. 12
0
NTSTATUS
VIOSerialPortEvtDeviceD0Exit(
    IN  WDFDEVICE Device,
    IN  WDF_POWER_DEVICE_STATE TargetState
    )
{
    PVIOSERIAL_PORT Port = RawPdoSerialPortGetData(Device)->port;
    PPORT_BUFFER buf;
    PSINGLE_LIST_ENTRY iter;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s TargetState: %d\n",
        __FUNCTION__, TargetState);

    Port->Removed = TRUE;

    VIOSerialDisableInterruptQueue(GetInQueue(Port));

    WdfSpinLockAcquire(Port->InBufLock);
    VIOSerialDiscardPortDataLocked(Port);
    Port->InBuf = NULL;
    WdfSpinLockRelease(Port->InBufLock);

    VIOSerialReclaimConsumedBuffers(Port);

    while (buf = (PPORT_BUFFER)virtqueue_detach_unused_buf(GetInQueue(Port)))
    {
        VIOSerialFreeBuffer(buf);
    }

    iter = PopEntryList(&Port->WriteBuffersList);
    while (iter != NULL)
    {
        PWRITE_BUFFER_ENTRY entry = CONTAINING_RECORD(iter,
            WRITE_BUFFER_ENTRY, ListEntry);

        ExFreePoolWithTag(entry->Buffer, VIOSERIAL_DRIVER_MEMORY_TAG);
        WdfObjectDelete(entry->EntryHandle);

        iter = PopEntryList(&Port->WriteBuffersList);
    };

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s\n", __FUNCTION__);

    return STATUS_SUCCESS;
}
Esempio n. 13
0
NTSTATUS CyGetAndParseUSB30DeviceConfiguration(__in PDEVICE_CONTEXT pDevContext)
 {
	 NTSTATUS NtStatus = STATUS_SUCCESS;
	 WDFMEMORY pUsb30DeviceConfig =NULL;
	 PVOID pUsb30DeviceConfigBuf =NULL;
	 size_t szUsb30DeviceConfigBufSize =0;
	 // Get Device configuration.
	 NtStatus = CyGetUSB30DeviceConfiguration(pDevContext,&pUsb30DeviceConfig);
	 if (NT_SUCCESS(NtStatus) && pUsb30DeviceConfig) 
	 {
		 pUsb30DeviceConfigBuf = WdfMemoryGetBuffer(pUsb30DeviceConfig,&szUsb30DeviceConfigBufSize);
		 //Parse and store the Enpoint companion descriptor
		 CyParseAndStoreUSB30DeviceConfiguration(pDevContext,pUsb30DeviceConfigBuf,szUsb30DeviceConfigBufSize);

		 // Delete the device configuration memory object as it's no longer needed
	     WdfObjectDelete(pUsb30DeviceConfig);
	 }
	 
	 return NtStatus;
 }
Esempio n. 14
0
_Use_decl_annotations_
VOID
BthEchoEvtConnectionObjectCleanup(
    WDFOBJECT  ConnectionObject
    )
/*++

Description:

    This routine is invoked by the Framework when connection object
    gets deleted (either explicitly or implicitly because of parent
    deletion).

    Since we mark ExecutionLevel as passive for connection object we get this
    callback at passive level and can wait for stopping of continuous
    readers and for disconnect to complete.

Arguments:

    ConnectionObject - The Connection Object

Return Value:

    None

--*/
{
    PBTHECHO_CONNECTION connection = GetConnectionObjectContext(ConnectionObject);

    PAGED_CODE();
        
    BthEchoConnectionObjectWaitForAndUninitializeContinuousReader(connection);

    KeWaitForSingleObject(&connection->DisconnectEvent,
        Executive,
        KernelMode,
        FALSE,
        NULL);

    WdfObjectDelete(connection->ConnectDisconnectRequest);
}
// This routine perform a simulator cleanup
// Returns an NTSTATUS code
NTSTATUS HardwareSimulator::Cleanup()
{
    NTSTATUS status = STATUS_SUCCESS;

    if (SimulatorState_Started == m_State)
    {
        Stop();
    }

    // Delete lock
    if (NULL != m_Lock)
    {
        WdfObjectDelete(m_Lock);
        m_Lock = NULL;
    }

    // Set the simulator state to "not initialized"
    m_State = SimulatorState_NotInitialized;

    return status;
}
Esempio n. 16
0
/**
 * @brief generic workitem callback function 
 * calls the specific callback function in the work item context.
 * 
 * @param[in] WorkItem handle to the workitem object.
 * 
 */
VOID
EvtFdoDeviceGenericWorkItem (
    IN WDFWORKITEM  WorkItem)
{
    PUSB_FDO_WORK_ITEM_CONTEXT  context = WorkItemGetContext(WorkItem);
    //
    // NULL indicates somebody screwed up, log it and forget it.
    //
    if (context->CallBack)
    {
        context->CallBack(WorkItem);
    }
    else
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            __FUNCTION__": %s Device %p WorkItem %p NULL callback\n",            
            context->FdoContext->FrontEndPath,
            context->FdoContext->WdfDevice,
            WorkItem);
    }
    context->CallBack = NULL;
    //
    // put this workitem into our collection.
    //
    AcquireFdoLock(context->FdoContext);
    NTSTATUS Status = WdfCollectionAdd(context->FdoContext->FreeWorkItems, WorkItem);
    ReleaseFdoLock(context->FdoContext);

    if (!NT_SUCCESS(Status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            __FUNCTION__": %s Device %p WdfCollectionAdd error %x deleting workitem %p\n",
            context->FdoContext->FrontEndPath,
            context->FdoContext->WdfDevice,
            Status,
            WorkItem);
        // oh well delete it
        WdfObjectDelete(WorkItem);
    }
}
Esempio n. 17
0
VOID
EchoEvtIoQueueContextDestroy(
    WDFOBJECT Object
)
/*++

Routine Description:

    This is called when the Queue that our driver context memory
    is associated with is destroyed.

Arguments:

    Context - Context that's being freed.

Return Value:

    VOID

--*/
{
    PQUEUE_CONTEXT queueContext = QueueGetContext(Object);

    //
    // Release any resources pointed to in the queue context.
    //
    // The body of the queue context will be released after
    // this callback handler returns
    //

    //
    // If Queue context has an I/O buffer, release it
    //
    if( queueContext->WriteMemory != NULL ) {
        WdfObjectDelete(queueContext->WriteMemory);
        queueContext->WriteMemory = NULL;
    }

    return;
}
static VOID
XenVbd_SendEventComplete(WDFREQUEST request, WDFIOTARGET target, PWDF_REQUEST_COMPLETION_PARAMS params, WDFCONTEXT context) {
  WDFDEVICE device = WdfIoTargetGetDevice(target);
  PXENVBD_FILTER_DATA xvfd = GetXvfd(device);
  NTSTATUS status;
  PSCSI_REQUEST_BLOCK srb = context;
  LARGE_INTEGER systemtime;
  ULONGLONG elapsed;

  UNREFERENCED_PARAMETER(params);
  UNREFERENCED_PARAMETER(context);

  status = WdfRequestGetStatus(request);
  if (status != 0 || srb->SrbStatus != SRB_STATUS_SUCCESS) {
    FUNCTION_MSG("Request Status = %08x, SRB Status = %08x\n", status, srb->SrbStatus);
  }
  KeQuerySystemTime(&systemtime);
  elapsed = systemtime.QuadPart - ((PLARGE_INTEGER)((PUCHAR)context + sizeof(SCSI_REQUEST_BLOCK) + sizeof(SRB_IO_CONTROL)))->QuadPart;
  elapsed = elapsed / 10000; // now in ms
  if (elapsed > 1000) {
    FUNCTION_MSG("Event took %d ms\n", (ULONG)elapsed);
  }
  ExFreePoolWithTag(context, XENVBD_POOL_TAG);
  WdfObjectDelete(request);

  for (;;) {
    if (InterlockedCompareExchange(&xvfd->event_state, 0, 1) == 1) {
      /* no pending event, and we cleared outstanding flag */
      break;
    }
    if (InterlockedCompareExchange(&xvfd->event_state, 1, 2) == 2) {
      /* there was a pending event, and we set the flag back to outstanding */
      //FUNCTION_MSG("sending pended event\n");
      XenVbd_SendEvent(device);
      break;
    }
    /* event_state changed while we were looking at it, go round again */
  }
}
Esempio n. 19
0
VOID Interface_DeletePipesAndQueues(__in PINTERFACE_CONTEXT interfaceContext)
{
	UCHAR pipeIndex;

	for (pipeIndex = 0; pipeIndex < interfaceContext->PipeCount; pipeIndex++)
	{
		PPIPE_CONTEXT pipeContext = interfaceContext->PipeContextByIndex[pipeIndex];
		
		// this needs to be re-initialized in subsequent code but we null it here
		// because nothing else should be using it at this point.
		interfaceContext->PipeContextByIndex[pipeIndex] = NULL;

		if (!pipeContext)
		{
			// should certainly never happen; indicates corrupted memory
			USBERRN("NULL pipeContext at index %u. Memory may be corrupt!", pipeIndex);
			continue;
		}

		// the context should always be marked invalid at this point
		// delete the queues for all pipes associated with this interface
		if (pipeContext->IsValid == FALSE && 
			pipeContext->Queue != WDF_NO_HANDLE && 
			(pipeContext->PipeInformation.EndpointAddress & 0xF))
		{
			USBDBGN("pipeID=%02Xh Destroying pipe queue.", pipeContext->PipeInformation.EndpointAddress);
			WdfObjectDelete(pipeContext->Queue);
			pipeContext->Queue = WDF_NO_HANDLE;
		}

		// mark the pipe handle as null.  The framework destroys these for us.
		pipeContext->Pipe = WDF_NO_HANDLE;
	}

	// set the pipe count to zero
	interfaceContext->PipeCount = 0;
}
Esempio n. 20
0
VOID
Rio500_EvtReadWriteWorkItem(
  _In_ WDFWORKITEM  WorkItem
)
{
  PWORKITEM_CONTEXT pItemContext;
  NTSTATUS status;

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

  pItemContext = GetWorkItemContext(WorkItem);

  status = ResetPipe(pItemContext->Pipe);
  if (!NT_SUCCESS(status)) {
    Rio500_DbgPrint(1, ("ResetPipe failed 0x%x\n", status));

    status = ResetDevice(pItemContext->Device);
    if (!NT_SUCCESS(status)) {
      Rio500_DbgPrint(1, ("ResetDevice failed 0x%x\n", status));
    }
  }

  WdfObjectDelete(WorkItem);
}
Esempio n. 21
0
VOID
PepWorkerWrapper (
    _In_ WDFWORKITEM WorkItem
    )

/*++

Routine Description:

    This routine is wrapper for the actual worker routine that processes
    pending work.

Arguments:

    WorkItem -  Supplies a handle to the workitem supplying the context.

Return Value:

    None.

--*/

{

    PPEP_WORK_ITEM_CONTEXT Context;

    Context = PepGetWorkItemContext(WorkItem);
    PepProcessPendingWorkRequests();

    //
    // Delete the work item as it is no longer required.
    //

    WdfObjectDelete(WorkItem);
    return;
}
NTSTATUS AndroidUsbPipeFileObject::QueueResetPipePassiveCallback() {
  ASSERT_IRQL_LOW_OR_DISPATCH();

  // Initialize workitem
  WDF_OBJECT_ATTRIBUTES attr;
  WDF_OBJECT_ATTRIBUTES_INIT(&attr);
  WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&attr, AndroidUsbWorkitemContext);
  attr.ParentObject = wdf_device();

  WDFWORKITEM wdf_work_item = NULL;
  WDF_WORKITEM_CONFIG workitem_config;
  WDF_WORKITEM_CONFIG_INIT(&workitem_config, ResetPipePassiveCallbackEntry);
  NTSTATUS status = WdfWorkItemCreate(&workitem_config,
                                      &attr,
                                      &wdf_work_item);
  ASSERT(NT_SUCCESS(status) && (NULL != wdf_work_item));
  if (!NT_SUCCESS(status))
    return status;

  // Initialize our extension to work item
  AndroidUsbWorkitemContext* context =
    GetAndroidUsbWorkitemContext(wdf_work_item);
  ASSERT(NULL != context);
  if (NULL == context) {
    WdfObjectDelete(wdf_work_item);
    return STATUS_INTERNAL_ERROR;
  }

  context->object_type = AndroidUsbWdfObjectTypeWorkitem;
  context->pipe_file_ext = this;

  // Enqueue this work item.
  WdfWorkItemEnqueue(wdf_work_item);

  return STATUS_SUCCESS;
}
Esempio n. 23
0
VOID
EchoEvtIoWrite(
    IN WDFQUEUE   Queue,
    IN WDFREQUEST Request,
    IN size_t     Length
    )
/*++

Routine Description:

    This event is invoked when the framework receives IRP_MJ_WRITE request.
    This routine allocates memory buffer, copies the data from the request to it,
    and stores the buffer pointer in the queue-context with the length variable
    representing the buffers length. The actual completion of the request
    is defered to the periodic timer dpc.

Arguments:

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

    Request - Handle to a framework request object.

    Length  - number of bytes to be read.
              The default property of the queue is to not dispatch
              zero lenght read & write requests to the driver and
              complete is with status success. So we will never get
              a zero length request.

Return Value:

    VOID

--*/
{
    NTSTATUS Status;
    WDFMEMORY memory;
    PQUEUE_CONTEXT queueContext = QueueGetContext(Queue);
    PVOID writeBuffer = NULL;

    _Analysis_assume_(Length > 0);

    KdPrint(("EchoEvtIoWrite Called! Queue 0x%p, Request 0x%p Length %d\n",
             Queue,Request,Length));

    if( Length > MAX_WRITE_LENGTH ) {
        KdPrint(("EchoEvtIoWrite Buffer Length to big %d, Max is %d\n",
                 Length,MAX_WRITE_LENGTH));
        WdfRequestCompleteWithInformation(Request, STATUS_BUFFER_OVERFLOW, 0L);
        return;
    }

    // Get the memory buffer
    Status = WdfRequestRetrieveInputMemory(Request, &memory);
    if( !NT_SUCCESS(Status) ) {
        KdPrint(("EchoEvtIoWrite Could not get request memory buffer 0x%x\n",
                 Status));
        WdfVerifierDbgBreakPoint();
        WdfRequestComplete(Request, Status);
        return;
    }

    // Release previous buffer if set
    if( queueContext->WriteMemory != NULL ) {
        WdfObjectDelete(queueContext->WriteMemory);
        queueContext->WriteMemory = NULL;
    }

    Status = WdfMemoryCreate(WDF_NO_OBJECT_ATTRIBUTES,
                             NonPagedPool,
                             'sam1',
                             Length,
                             &queueContext->WriteMemory,
                             &writeBuffer
                             );

    if(!NT_SUCCESS(Status)) {
        KdPrint(("EchoEvtIoWrite: Could not allocate %d byte buffer\n", Length));
        WdfRequestComplete(Request, STATUS_INSUFFICIENT_RESOURCES);
        return;
    }


    // Copy the memory in
    Status = WdfMemoryCopyToBuffer( memory,
                                    0,  // offset into the source memory
                                    writeBuffer,
                                    Length );
    if( !NT_SUCCESS(Status) ) {
        KdPrint(("EchoEvtIoWrite WdfMemoryCopyToBuffer failed 0x%x\n", Status));
        WdfVerifierDbgBreakPoint();

        WdfObjectDelete(queueContext->WriteMemory);
        queueContext->WriteMemory = NULL;

        WdfRequestComplete(Request, Status);
        return;
    }

    // Set transfer information
    WdfRequestSetInformation(Request, (ULONG_PTR)Length);

    // Specify the request is cancelable
    WdfRequestMarkCancelable(Request, EchoEvtRequestCancel);

    // Defer the completion to another thread from the timer dpc
    queueContext->CurrentRequest = Request;
    queueContext->CurrentStatus  = Status;

    return;
}
// This routine is called by the framework when the PnP manager is revoking
// ownership of our resources. This may be in response to either
// IRP_MN_STOP_DEVICE or IRP_MN_REMOVE_DEVICE. This routine is responsible for
// performing cleanup of resources allocated in PrepareHardware callback.
// This callback is invoked before passing  the request down to the lower driver.
// This routine will also be invoked by the framework if the prepare hardware
// callback returns a failure.
NTSTATUS
CustomSensorDevice::OnReleaseHardware(
    _In_ WDFDEVICE Device,                       // Supplies a handle to the framework device object
    _In_ WDFCMRESLIST /*ResourcesTranslated*/)   // Supplies a handle to a collection of framework
// resource objects. This collection identifies the translated
// (system-physical) hardware resources that have been assigned to the
// device. The resources appear from the CPU's point of view.
{
    PHardwareSimulator pSimulator = nullptr;
    PCustomSensorDevice pDevice = nullptr;
    SENSOROBJECT SensorInstance = nullptr;
    ULONG SensorInstanceCount = 1;    // only expect 1 sensor instance
    NTSTATUS Status = STATUS_SUCCESS;

    SENSOR_FunctionEnter();

    // Get sensor instance
    Status = SensorsCxDeviceGetSensorList(Device, &SensorInstance, &SensorInstanceCount);
    if (!NT_SUCCESS(Status) ||
            0 == SensorInstanceCount ||
            NULL == SensorInstance)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! SensorsCxDeviceGetSensorList failed %!STATUS!", Status);
        goto Exit;
    }

    pDevice = GetCustomSensorContextFromSensorInstance(SensorInstance);
    if (nullptr == pDevice)
    {
        Status = STATUS_INVALID_PARAMETER;
        TraceError("CSTM %!FUNC! GetCustomSensorContextFromSensorInstance failed %!STATUS!", Status);
        goto Exit;
    }

    // Delete lock
    if (pDevice->m_Lock)
    {
        WdfObjectDelete(pDevice->m_Lock);
        pDevice->m_Lock = NULL;
    }

    // Cleanup the CO2 simulator
    pSimulator = GetHardwareSimulatorContextFromInstance(pDevice->m_SimulatorInstance);
    if (nullptr == pSimulator)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        TraceError("CSTM %!FUNC! GetHardwareSimulatorContextFromInstance failed %!STATUS!", Status);
        goto Exit;
    }

    pSimulator->Cleanup();

    // Delete hardware simulator instance
    if (NULL != pDevice->m_SimulatorInstance)
    {
        WdfObjectDelete(pDevice->m_SimulatorInstance);
        pDevice->m_SimulatorInstance = NULL;
    }

    // Delete sensor instance
    if (NULL != pDevice->m_SensorInstance)
    {
        WdfObjectDelete(pDevice->m_SensorInstance);
    }

Exit:
    SENSOR_FunctionExit(Status);
    return Status;
}
Esempio n. 25
0
NTSTATUS PciDtfDeviceAllocDma(IN WDFDEVICE Device, IN WDFREQUEST Request)
{
	PDEVICE_DATA DeviceData = GetDeviceData(Device);
	PCIDTF_DMA_INFO *ReqData;
	WDF_OBJECT_ATTRIBUTES ObjectAttributes;
	WDFCOMMONBUFFER CommonBuffer = NULL;
	PCOMMON_BUFFER_DATA CommonBufferData;
	NTSTATUS Status = STATUS_SUCCESS;

	__try {
		Status = WdfRequestRetrieveInputBuffer(Request,
						       sizeof(PCIDTF_DMA_INFO),
						       (PVOID *) & ReqData,
						       NULL);
		if (!NT_SUCCESS(Status)) {
			TRACE_ERR("WdfRequestRetrieveInputBuffer", Status);
			__leave;
		}
		Status = WdfRequestRetrieveOutputBuffer(Request,
							sizeof(PCIDTF_DMA_INFO),
							(PVOID *) & ReqData,
							NULL);
		if (!NT_SUCCESS(Status)) {
			TRACE_ERR("WdfRequestRetrieveOutputBuffer", Status);
			__leave;
		}
		WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&ObjectAttributes,
							COMMON_BUFFER_DATA);
		Status = WdfCommonBufferCreate(DeviceData->DmaEnabler,
					       ReqData->len, &ObjectAttributes,
					       &CommonBuffer);
		if (!NT_SUCCESS(Status)) {
			TRACE_ERR("WdfCommonBufferCreate", Status);
			__leave;
		}
		CommonBufferData = GetCommonBufferData(CommonBuffer);
		CommonBufferData->ID = PciDtfCommonBufferAssignId(DeviceData);
		Status = WdfCollectionAdd(DeviceData->CommonBuffers,
					  CommonBuffer);
		if (!NT_SUCCESS(Status)) {
			TRACE_ERR("WdfCollectionAdd", Status);
			__leave;
		}
		ReqData->id = CommonBufferData->ID;
		ReqData->addr =
		    WdfCommonBufferGetAlignedLogicalAddress
		    (CommonBuffer).QuadPart;
		WdfRequestSetInformation(Request, sizeof(PCIDTF_DMA_INFO));

		TRACE_MSG(TRACE_LEVEL_VERBOSE, TRACE_FLAG_QUEUE,
			  "va 0x%p, pa 0x%llX, len 0x%X\n",
			  WdfCommonBufferGetAlignedVirtualAddress(CommonBuffer),
			  WdfCommonBufferGetAlignedLogicalAddress
			  (CommonBuffer).QuadPart,
			  WdfCommonBufferGetLength(CommonBuffer));
	}
	__finally {
		if (!NT_SUCCESS(Status) && CommonBuffer != NULL) {
			WdfObjectDelete(CommonBuffer);
		}
		WdfRequestComplete(Request, Status);
	}
	return Status;
}
Esempio n. 26
0
NTSTATUS
BthEchoCliRetrieveServerSdpRecord(
    __in PBTHECHOSAMPLE_CLIENT_CONTEXT DevCtx,
    __out PBTH_SDP_STREAM_RESPONSE * ServerSdpRecord    
    )
/*++

Description:

    Retrive server SDP record.
    We call this function on every file open to get the PSM

Arguments:

    DevCtx - Client context
    ServerSdpRecord - SDP record retrieved

Return Value:

    NTSTATUS Status code.

--*/
{
    NTSTATUS status, statusReuse, disconnectStatus;
    WDF_MEMORY_DESCRIPTOR inMemDesc;
    WDF_MEMORY_DESCRIPTOR outMemDesc;
    WDF_REQUEST_REUSE_PARAMS ReuseParams;    
    BTH_SDP_CONNECT connect = {0};
    BTH_SDP_DISCONNECT disconnect = {0};
    BTH_SDP_SERVICE_ATTRIBUTE_SEARCH_REQUEST requestSdp = {0};
    BTH_SDP_STREAM_RESPONSE responseSdp = {0};
    ULONG requestSize;
    PBTH_SDP_STREAM_RESPONSE serverSdpRecord = NULL;
    WDFREQUEST request;
    WDF_OBJECT_ATTRIBUTES attributes;
    

    PAGED_CODE();

    //
    // Allocate the request we will use for obtaining sdp record
    // NOTE that we do it for every file open, hence we
    //
    // can't use reserve request from the context
    //
    
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);

    status = WdfRequestCreate(
        &attributes,
        DevCtx->Header.IoTarget,
        &request
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
            "Failed to allocate request for retriving server sdp record, Status code %!STATUS!\n", status);

        goto exit;        
    }

    connect.bthAddress = DevCtx->ServerBthAddress;
    connect.requestTimeout = SDP_REQUEST_TO_DEFAULT;
    connect.fSdpConnect = 0;

    //
    // Connect to the SDP service.
    //

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &connect,
        sizeof(connect)
        );
    
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &outMemDesc,
        &connect,
        sizeof(connect)
        );

    status = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_CONNECT,
        &inMemDesc,
        &outMemDesc,
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
            "IOCTL_BTH_SDP_CONNECT failed, Status code %!STATUS!\n", status);

        goto exit1;
    }

    //
    // Obtain the required size of the SDP record
    //
    requestSdp.hConnection = connect.hConnection;
    requestSdp.uuids[0].u.uuid128 = BTHECHOSAMPLE_SVC_GUID;
    requestSdp.uuids[0].uuidType = SDP_ST_UUID128;
    requestSdp.range[0].minAttribute = 0;
    requestSdp.range[0].maxAttribute = 0xFFFF;

    WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED);
    statusReuse = WdfRequestReuse(request, &ReuseParams);    
    ASSERT(NT_SUCCESS(statusReuse));
    UNREFERENCED_PARAMETER(statusReuse);

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &requestSdp,
        sizeof(requestSdp)
        );
    
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &outMemDesc,
        &responseSdp,
        sizeof(responseSdp)
        );

    status = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH,
        &inMemDesc,
        &outMemDesc,
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH failed while querying response size, "
            "status code %!STATUS!\n", status);

        goto exit2;
    }

    //
    // Allocate the required size for SDP record
    //

    status = RtlULongAdd(
        responseSdp.requiredSize, 
        sizeof(BTH_SDP_STREAM_RESPONSE), 
        &requestSize
        );

    if(!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "SDP record size too large, status code %!STATUS!\n", status);

        goto exit2;
    }

    serverSdpRecord = ExAllocatePoolWithTag(NonPagedPool, requestSize, POOLTAG_BTHECHOSAMPLE);
    if (NULL == serverSdpRecord)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "Allocating SDP record failed, returning status code %!STATUS!\n", status); 

        goto exit2;
    }

    //
    // Send request with required size
    //
    
    WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED);
    statusReuse = WdfRequestReuse(request, &ReuseParams);    
    ASSERT(NT_SUCCESS(statusReuse));
    UNREFERENCED_PARAMETER(statusReuse);

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &requestSdp,
        sizeof(requestSdp)
        );
    
    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &outMemDesc,
        serverSdpRecord,
        requestSize
        );

    status = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH,
        &inMemDesc,
        &outMemDesc,
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, 
            "IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH failed, status code %!STATUS!\n", status);

        ExFreePoolWithTag(serverSdpRecord, POOLTAG_BTHECHOSAMPLE);
    }
    else
    {
        *ServerSdpRecord = serverSdpRecord;
    }
    
exit2:
    
    //
    // Disconnect from SDP service.
    //
    
    WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED);
    statusReuse = WdfRequestReuse(request, &ReuseParams);    
    ASSERT(NT_SUCCESS(statusReuse));
    UNREFERENCED_PARAMETER(statusReuse);

    disconnect.hConnection = connect.hConnection;

    WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
        &inMemDesc,
        &disconnect,
        sizeof(disconnect)
        );
    
    disconnectStatus = WdfIoTargetSendIoctlSynchronously(
        DevCtx->Header.IoTarget,
        request,
        IOCTL_BTH_SDP_DISCONNECT,
        &inMemDesc,
        NULL,   //outMemDesc
        NULL,   //sendOptions
        NULL    //bytesReturned
        );

    ASSERT(NT_SUCCESS(disconnectStatus)); //Disconnect should not fail

    if (!NT_SUCCESS(disconnectStatus))
    {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, 
            "IOCTL_BTH_SDP_DISCONNECT failed, Status code %!STATUS!\n", status);
    }
    
exit1:    
    WdfObjectDelete(request);
exit:
    return status;
}
Esempio n. 27
0
//
// PRE REQUIREMENTS:
// * pipeContext->IsValid == FALSE
// * Queue(if any) must be stopped
// * IoTarget must be stopped
//
// On return the pipe and queue are started and the context is marked valid again.
//
NTSTATUS Pipe_InitContext(__in PDEVICE_CONTEXT deviceContext,
                          __in PPIPE_CONTEXT pipeContext,
						  __in BOOLEAN startIoTarget)
{
	NTSTATUS status = STATUS_INVALID_HANDLE;
	WDFQUEUE queueOld	= pipeContext->Queue;
	WDFQUEUE queueNew	= NULL;

	if (!pipeContext->Pipe && pipeContext->PipeInformation.PipeType != WdfUsbPipeTypeControl)
	{
		USBERR("pipeID=%02Xh invalid pipe handle\n", pipeContext->PipeInformation.EndpointAddress);
		goto Done;
	}

	if (queueOld == NULL || ((pipeContext->PipeInformation.EndpointAddress & 0xF) && pipeContext->IsQueueDirty))
	{
		pipeContext->IsQueueDirty = FALSE;
		if (queueOld != NULL)
		{
			// We need to delete the old pipe queue.
			USBDBGN("pipeID=%02Xh Destroying old pipe queue.", pipeContext->PipeInformation.EndpointAddress);
			WdfObjectDelete(queueOld);
			queueOld = NULL;
		}
		USBDBGN("pipeID=%02Xh Creating pipe queue.", pipeContext->PipeInformation.EndpointAddress);
		status = Pipe_InitQueue(deviceContext, pipeContext, &queueNew);
		if (!NT_SUCCESS(status))
		{
			pipeContext->Queue = NULL;
			pipeContext->IsValid = FALSE;
			USBERRN("Pipe_InitQueue failed. pipeID=%02Xh status=%08Xh", pipeContext->PipeInformation.EndpointAddress, status);
			goto Done;
		}

		pipeContext->Queue = queueNew;
		
	}
	else
	{
		// Queue is already created and does not need to be updated.
		status = STATUS_SUCCESS;
		queueNew = queueOld;
	}
	if (!queueNew && NT_SUCCESS(status))
		status = STATUS_INVALID_PIPE_STATE;

	if (NT_SUCCESS(status))
	{
		if (pipeContext->PipeInformation.PipeType != WdfUsbPipeTypeControl)
		{
			if (startIoTarget)
			{
				// start pipe
				USBDBG("pipeID=%02Xh starting..\n", pipeContext->PipeInformation.EndpointAddress);
				
				status = PipeStart(pipeContext);
				if (!NT_SUCCESS(status))
				{
					pipeContext->IsValid = FALSE;
					USBERR("WdfIoTargetStart failed. status=%Xh\n", status);
					goto Done;
				}
			}
		}

		// start queue
		USBDBG("pipeID=%02Xh queue starting..\n", pipeContext->PipeInformation.EndpointAddress);
		WdfIoQueueStart(queueNew);
		pipeContext->IsValid = TRUE;

	}
	else
	{
		USBERR("WdfIoQueueCreate failed. status=%Xh\n", status);
		pipeContext->IsValid = FALSE;
		goto Done;
	}

Done:
	return status;
}
Esempio n. 28
0
NTSTATUS Pipe_InitQueue(
    __in PDEVICE_CONTEXT deviceContext,
    __in PPIPE_CONTEXT pipeContext,
    __out WDFQUEUE* queueRef)
{
	WDF_IO_QUEUE_CONFIG queueConfig;
	WDF_OBJECT_ATTRIBUTES objectAttributes;
	NTSTATUS status = STATUS_INVALID_HANDLE;
	WDFQUEUE queue = NULL;
	PQUEUE_CONTEXT queueContext;
	WDF_OBJECT_ATTRIBUTES memAttributes;

	WDF_OBJECT_ATTRIBUTES_INIT(&objectAttributes);
	objectAttributes.SynchronizationScope = WdfSynchronizationScopeQueue;

	*queueRef = NULL;

	// All queues get a context. At the very least, they will use a local copy of policy and pipe information
	WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&objectAttributes, QUEUE_CONTEXT);

	queueConfig.DispatchType = WdfIoQueueDispatchInvalid;
	Pipe_InitQueueConfig(pipeContext, &queueConfig);

	if (queueConfig.DispatchType != WdfIoQueueDispatchInvalid)
	{
		status = WdfIoQueueCreate(deviceContext->WdfDevice,
		                          &queueConfig,
		                          &objectAttributes,
		                          &queue);
		if (!NT_SUCCESS(status))
		{
			USBERR("WdfIoQueueCreate failed. pipeID=%02Xh status=%Xh\n", pipeContext->PipeInformation.EndpointAddress, status);
			goto Exit;
		}

		// Create the memory for partial read storage
		queueContext = GetQueueContext(queue);

		queueContext->IsFreshPipeReset = TRUE;

		// SET queueContext->OverOfs
		RtlZeroMemory(&queueContext->OverOfs, sizeof(queueContext->OverOfs));

		// SET queueContext->PipeHandle
		queueContext->PipeHandle = pipeContext->Pipe;

		// SET queueContext->Info
		RtlCopyMemory(&queueContext->Info, &pipeContext->PipeInformation, sizeof(queueContext->Info));

		WDF_OBJECT_ATTRIBUTES_INIT(&memAttributes);
		memAttributes.ParentObject = queue;

		// Only bulk and interrupt pipes have an OverMem buffer and it is only used
		// when the queue type is sequential. (RAW_IO=FALSE)
		if ((queueContext->Info.MaximumPacketSize) &&
		        (queueContext->Info.PipeType == WdfUsbPipeTypeBulk || queueContext->Info.PipeType == WdfUsbPipeTypeInterrupt))
		{
			// SET queueContext->OverMem
			// SET queueContext->OverBuf
			status = WdfMemoryCreate(&memAttributes, NonPagedPool, POOL_TAG, queueContext->Info.MaximumPacketSize, &queueContext->OverMem, &queueContext->OverBuf);
			if (!NT_SUCCESS(status))
			{
				USBERRN("WdfMemoryCreate failed. status=%08Xh", status);
				WdfObjectDelete(queue);
				goto Exit;
			}
		}
	}

	*queueRef = queue;

Exit:
	return status;
}
Esempio n. 29
0
NTSTATUS
NICInitiateDmaTransfer(
    IN PFDO_DATA        FdoData,
    IN WDFREQUEST       Request
    )
{
    WDFDMATRANSACTION   dmaTransaction;
    NTSTATUS            status;
    BOOLEAN             bCreated = FALSE;

    do {
        //
        // Create a new DmaTransaction.
        //
        status = WdfDmaTransactionCreate( FdoData->WdfDmaEnabler,
                                          WDF_NO_OBJECT_ATTRIBUTES,
                                          &dmaTransaction );

        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                        "WdfDmaTransactionCreate failed %X\n", status);
            break;
        }

        bCreated = TRUE;
        //
        // Initialize the new DmaTransaction.
        //

        status = WdfDmaTransactionInitializeUsingRequest(
                                     dmaTransaction,
                                     Request,
                                     NICEvtProgramDmaFunction,
                                     WdfDmaDirectionWriteToDevice );

        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                       "WdfDmaTransactionInitalizeUsingRequest failed %X\n",
                       status);
            break;
        }

        //
        // Execute this DmaTransaction.
        //
        status = WdfDmaTransactionExecute( dmaTransaction,
                                           dmaTransaction );

        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                            "WdfDmaTransactionExecute failed %X\n", status);
            break;
        }

    } WHILE (FALSE);

    if(!NT_SUCCESS(status)){

        if(bCreated) {
            WdfObjectDelete( dmaTransaction );

        }
    }

    return status;
}
Esempio n. 30
0
BOOLEAN
NICEvtProgramDmaFunction(
    IN  WDFDMATRANSACTION       Transaction,
    IN  WDFDEVICE               Device,
    IN  PVOID                   Context,
    IN  WDF_DMA_DIRECTION       Direction,
    IN  PSCATTER_GATHER_LIST    ScatterGather
    )
/*++

Routine Description:

Arguments:

Return Value:

--*/
{
    PFDO_DATA           fdoData;
    WDFREQUEST          request;
    NTSTATUS            status;

    UNREFERENCED_PARAMETER( Context );
    UNREFERENCED_PARAMETER( Direction );

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "--> NICEvtProgramDmaFunction\n");

    fdoData = FdoGetData(Device);
    request = WdfDmaTransactionGetRequest(Transaction);


    WdfSpinLockAcquire(fdoData->SendLock);

    //
    // If tcb or link is not available, queue the request
    //
    if (!MP_TCB_RESOURCES_AVAIABLE(fdoData))
    {
        TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "Resource is not available: queue Request %p\n", request);

        //
        // Must abort the transaction before deleting.
        //
        (VOID) WdfDmaTransactionDmaCompletedFinal(Transaction, 0, &status);
        ASSERT(NT_SUCCESS(status));
        WdfObjectDelete( Transaction );

        //
        // Queue the request for later processing.
        //
        status = WdfRequestForwardToIoQueue(request,
                                           fdoData->PendingWriteQueue);

        if(!NT_SUCCESS(status)) {
            ASSERTMSG(" WdfRequestForwardToIoQueue failed ", FALSE);
            WdfSpinLockRelease(fdoData->SendLock);
            WdfRequestCompleteWithInformation(request, STATUS_UNSUCCESSFUL, 0);
            return FALSE;
        }
        fdoData->nWaitSend++;

    } else {

        status = NICWritePacket(fdoData, Transaction, ScatterGather);

        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE,
                        "<-- NICEvtProgramDmaFunction returning %!STATUS!\n",
                        status);
            //
            // Must abort the transaction before deleting.
            //
            (VOID )WdfDmaTransactionDmaCompletedFinal(Transaction, 0, &status);
            ASSERT(NT_SUCCESS(status));
            WdfObjectDelete( Transaction );

            WdfSpinLockRelease(fdoData->SendLock);
            WdfRequestCompleteWithInformation(request, STATUS_UNSUCCESSFUL, 0);
            return FALSE;
        }
    }


    WdfSpinLockRelease(fdoData->SendLock);

    TraceEvents(TRACE_LEVEL_VERBOSE, DBG_WRITE,
                "<-- NICEvtProgramDmaFunction\n");

    return TRUE;
}