示例#1
0
文件: Device.cpp 项目: OpenXT/xc-vusb
/** 
 * @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);
    }
}
示例#2
0
文件: Device.cpp 项目: OpenXT/xc-vusb
/**
 * @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);
    }
}
示例#3
0
NTSTATUS AddDefaultDeviceInterfaceGUID(__in PDEVICE_CONTEXT deviceContext)
{

	WDF_OBJECT_ATTRIBUTES	stringAttributes;
	UNICODE_STRING defaultDeviceInterfaceGUID_UnicodeString;
	WDFSTRING defaultDeviceInterfaceGUID = NULL;
	GUID guidTest = {0};
	NTSTATUS status;

	WDF_OBJECT_ATTRIBUTES_INIT(&stringAttributes);

	stringAttributes.ParentObject = deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs;

	RtlInitUnicodeString(&defaultDeviceInterfaceGUID_UnicodeString, LibusbKDeviceGuidW);

	status = WdfStringCreate(&defaultDeviceInterfaceGUID_UnicodeString, &stringAttributes, &defaultDeviceInterfaceGUID);
	if (!NT_SUCCESS(status))
	{
		USBERR("WdfStringCreate failed. status=%Xh\n", status);
		return status;
	}

	status = GUIDFromWdfString(defaultDeviceInterfaceGUID, &guidTest);
	if (!NT_SUCCESS(status))
	{
		USBERR("GUIDFromWdfString failed. status=%Xh\n", status);
		return status;
	}

	USBWRN("using default GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
	       guidTest.Data1,
	       guidTest.Data2,
	       guidTest.Data3,
	       guidTest.Data4[0], guidTest.Data4[1],
	       guidTest.Data4[2], guidTest.Data4[3], guidTest.Data4[4], guidTest.Data4[5], guidTest.Data4[6], guidTest.Data4[7]);

	return WdfCollectionAdd(deviceContext->DeviceRegSettings.DeviceInterfaceGUIDs, defaultDeviceInterfaceGUID);

}
示例#4
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;
}
示例#5
0
文件: toastmon.c 项目: kcrazy/winekit
NTSTATUS
ToastMon_PnpNotifyInterfaceChange(
    IN  PDEVICE_INTERFACE_CHANGE_NOTIFICATION NotificationStruct,
    IN  PVOID                        Context
    )
/*++

Routine Description:

    This routine is the PnP "interface change notification" callback routine.

    This gets called on a Toaster triggered device interface arrival or
    removal.
      - Interface arrival corresponds to a Toaster device being STARTED
      - Interface removal corresponds to a Toaster device being REMOVED

    On arrival:
      - Create a IoTarget and open it by using the symboliclink. WDF will
         Register for EventCategoryTargetDeviceChange notification on the fileobject
        so it can cleanup whenever associated device is removed.

    On removal:
      - This callback is a NO-OP for interface removal because framework registers
      for PnP EventCategoryTargetDeviceChange callbacks and
      uses that callback to clean up when the associated toaster device goes
      away.

Arguments:

    NotificationStruct  - Structure defining the change.

    Context -    pointer to the device extension.
                 (supplied as the "context" when we
                  registered for this callback)
Return Value:

    STATUS_SUCCESS - always, even if something goes wrong

    status is only used during query removal notifications and the OS ignores other
    cases

--*/
{
    NTSTATUS                    status = STATUS_SUCCESS;
    PDEVICE_EXTENSION           deviceExtension = Context;
    WDFIOTARGET                 ioTarget;

    PAGED_CODE();

    KdPrint(("Entered ToastMon_PnpNotifyInterfaceChange\n"));

    //
    // Verify that interface class is a toaster device interface.
    //
    ASSERT(IsEqualGUID( (LPGUID)&(NotificationStruct->InterfaceClassGuid),
                      (LPGUID)&GUID_DEVINTERFACE_TOASTER));

    //
    // Check the callback event.
    //
    if(IsEqualGUID( (LPGUID)&(NotificationStruct->Event),
                     (LPGUID)&GUID_DEVICE_INTERFACE_ARRIVAL )) {

        KdPrint(("Arrival Notification\n"));

        status = Toastmon_OpenDevice((WDFDEVICE)deviceExtension->WdfDevice,
                                                (PUNICODE_STRING)NotificationStruct->SymbolicLinkName,
                                                &ioTarget);
        if (!NT_SUCCESS(status)) {
            KdPrint( ("Unable to open control device 0x%x\n", status));
            return status;
        }

        //
        // Add this one to the collection.
        //
        WdfWaitLockAcquire(deviceExtension->TargetDeviceCollectionLock, NULL);

        //
        // WdfCollectionAdd takes a reference on the request object and removes
        // it when you call WdfCollectionRemove.
        //
        status = WdfCollectionAdd(deviceExtension->TargetDeviceCollection, ioTarget);
        if (!NT_SUCCESS(status)) {
            KdPrint( ("WdfCollectionAdd failed 0x%x\n", status));
            WdfObjectDelete(ioTarget); // Delete will also close the target
        }

        WdfWaitLockRelease(deviceExtension->TargetDeviceCollectionLock);


    } else {

        KdPrint(("Removal Interface Notification\n"));
    }
    return STATUS_SUCCESS;
}
示例#6
0
文件: Device.cpp 项目: OpenXT/xc-vusb
/**
 * @brief Called by the framework when a new PDO has arrived that this driver manages.
 * The device in question is not operational at this point in time.
 * 
 * @param[in] Driver handle to WDFDRIVER object created by DriverEntry()
 * @param[in,out] DeviceInit device init object provided by framework.
 * 
 * @returns NTSTATUS value indicating success or failure.
 * 
 */
NTSTATUS
FdoEvtDeviceAdd(
    _In_    WDFDRIVER       Driver,    
    _Inout_ PWDFDEVICE_INIT DeviceInit 
    )
{
    UNREFERENCED_PARAMETER(Driver);
    WDF_OBJECT_ATTRIBUTES   attributes;
    NTSTATUS status;

    TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE,
        __FUNCTION__"\n");
    
    WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
    WdfDeviceInitSetExclusive(DeviceInit, FALSE);
    WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, USB_FDO_CONTEXT);
    attributes.EvtCleanupCallback = FdoEvtDeviceContextCleanup;
    
    //
    // Device state callbacks.
    //
    WDF_PNPPOWER_EVENT_CALLBACKS    pnpPowerCallbacks;
    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
    pnpPowerCallbacks.EvtDevicePrepareHardware = FdoEvtDevicePrepareHardware;
    pnpPowerCallbacks.EvtDeviceReleaseHardware = FdoEvtDeviceReleaseHardware;
    pnpPowerCallbacks.EvtDeviceD0Entry = FdoEvtDeviceD0Entry;
    pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled = FdoEvtDeviceD0EntryPostInterruptsEnabled;
    pnpPowerCallbacks.EvtDeviceD0Exit  = FdoEvtDeviceD0Exit;
    pnpPowerCallbacks.EvtDeviceSurpriseRemoval = FdoEvtDeviceSurpriseRemoval;
    
    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
    //
    // establish a request context
    //
    WDF_OBJECT_ATTRIBUTES   requestAttributes;
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&requestAttributes, FDO_REQUEST_CONTEXT);
    WdfDeviceInitSetRequestAttributes(DeviceInit, &requestAttributes);

    //
    // static verifier seems to have a rule that the FDO must call 
    // WdfFdoInitSetDefaultChildListConfig if any component in the driver has
    // dynamic child devices, and the roothub has one if it is not operating in 
    // connect usb hub mode.
    //
    WDF_CHILD_LIST_CONFIG  config;
    WDF_CHILD_LIST_CONFIG_INIT(&config,
        sizeof(PDO_INDENTIFICATION_DESCRIPTION),
        FdoEvtChildListCreateDevice);

    WdfFdoInitSetDefaultChildListConfig(DeviceInit,
        &config,
        WDF_NO_OBJECT_ATTRIBUTES);
    //
    // add a preprocess callback for QueryInterface to support multi-version USBDI intefaces
    //
    UCHAR MinorFunctionTable[1] = {IRP_MN_QUERY_INTERFACE};

    status = WdfDeviceInitAssignWdmIrpPreprocessCallback(
        DeviceInit,
        FdoPreProcessQueryInterface,
        IRP_MJ_PNP,
        MinorFunctionTable,
        1);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            __FUNCTION__": WdfDeviceInitAssignWdmIrpPreprocessCallback failed error %x\n",
            status);
        return status;
    }

    //
    // Add create/close handlers
    //
    WDF_OBJECT_ATTRIBUTES   fileAttributes;
    WDF_OBJECT_ATTRIBUTES_INIT(&fileAttributes);
    fileAttributes.SynchronizationScope = WdfSynchronizationScopeNone;
    WDF_FILEOBJECT_CONFIG FileObjectConfig;
    WDF_FILEOBJECT_CONFIG_INIT(
        &FileObjectConfig,
        FdoEvtDeviceFileCreate,
        FdoEvtFileClose,
        WDF_NO_EVENT_CALLBACK);

    WdfDeviceInitSetFileObjectConfig(
        DeviceInit,
        &FileObjectConfig,
        &fileAttributes);
        
    WDFDEVICE device;
    status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            __FUNCTION__": WdfDeviceCreate failed error %x\n",
            status);
        return status;
    }

    PUSB_FDO_CONTEXT fdoContext = DeviceGetFdoContext(device);
    RtlZeroMemory(fdoContext, sizeof(USB_FDO_CONTEXT));
    fdoContext->WdfDevice = device;
    KeInitializeEvent(&fdoContext->resetCompleteEvent, SynchronizationEvent, FALSE);
    //
    // allocate the dpc request collection.
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = device;
    status = WdfCollectionCreate(&attributes,
        &fdoContext->RequestCollection);

    if (!NT_SUCCESS(status))
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
        __FUNCTION__": WdfCollectionCreate failed\n");
        return status;
    };
    //
    // The FDO is the USB Controller, create a device interface for that.
    //
    status = WdfDeviceCreateDeviceInterface(
        device,
        &GUID_DEVINTERFACE_USB_HOST_CONTROLLER,
        NULL);

    if (!NT_SUCCESS(status)) 
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            __FUNCTION__": WdfDeviceCreateDeviceInterface for device %p error %x\n",
            device,
            status);
        return status;
    }

    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);    
    attributes.ParentObject = device;
    status = WdfStringCreate(NULL, &attributes, &fdoContext->hcdsymlink);
    if (!NT_SUCCESS(status)) 
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            __FUNCTION__": WdfStringCreate for device %p error %x\n",
            device,
            status);
        return status;
    }

    status = WdfDeviceRetrieveDeviceInterfaceString(device,
        &GUID_DEVINTERFACE_USB_HOST_CONTROLLER,
        NULL,
        fdoContext->hcdsymlink);
    if (!NT_SUCCESS(status)) 
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
            __FUNCTION__": WdfStringCreate for device %p error %x\n",
            device,
            status);
        return status;
    }
    //
    // Some of our resources are independent of the device state and 
    // can be allocated/initialized here.
    //
    status = InitScratchpad(fdoContext);

    if (!NT_SUCCESS(status)) 
    {
        return status;
    }
    //
    // Initialize the I/O Package and any Queues
    //
    status = FdoQueueInitialize(device);
    if (!NT_SUCCESS(status)) 
    {
        return status;
    }

    //
    // --XT-- All of the WDF ISR and DPC setup code was removed
    // here. The DPC is now setup through the Xen interface in the
    // previous call. Note the event channel is setup but not active
    // until the backend is connected.
    //

    //
    // Allocate a watchdog timer for our Xen interface.
    //
    WDF_TIMER_CONFIG  timerConfig;
    WDF_OBJECT_ATTRIBUTES  timerAttributes;

    WDF_TIMER_CONFIG_INIT(
        &timerConfig,
        FdoEvtTimerFunc); 

    WDF_OBJECT_ATTRIBUTES_INIT(&timerAttributes);
    timerAttributes.ParentObject = device;
    timerAttributes.ExecutionLevel = WdfExecutionLevelPassive;

    status = WdfTimerCreate(
        &timerConfig,
        &timerAttributes,
        &fdoContext->WatchdogTimer);

    if (!NT_SUCCESS(status)) 
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
        __FUNCTION__": WdfTimerCreate error %x\n",
        status);
        return status;
    }

    //
    // Create a collection of work items.
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.ParentObject = device;
    status = WdfCollectionCreate(&attributes,
        &fdoContext->FreeWorkItems);
    if (!NT_SUCCESS(status)) 
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
        __FUNCTION__": WdfCollectionCreate error %x\n",
        status);
        return status;
    }

    for (ULONG index = 0; index < INIT_WORK_ITEM_COUNT; index++)
    {
        WDFWORKITEM workitem = NewWorkItem(fdoContext,
            NULL,
            0,0,0,0);
        if (workitem)
        {
            status = WdfCollectionAdd(fdoContext->FreeWorkItems, workitem);
            if (!NT_SUCCESS(status))
            {
                TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE,
                    __FUNCTION__": WdfCollectionAdd for workitem index %d error %x\n",
                    index,
                    status);
                
                WdfObjectDelete(workitem);
                return status;
            }
        }
    }

    PNP_BUS_INFORMATION  busInformation;
    busInformation.BusNumber = 0;
    busInformation.BusTypeGuid = GUID_BUS_TYPE_USB;
    busInformation.LegacyBusType = PNPBus;

    WdfDeviceSetBusInformationForChildren(
        device,
        &busInformation);

    if (NT_SUCCESS(status)) {
        status = LateSetup(device);
    }

    return status;
}
示例#7
0
文件: filter.c 项目: kcrazy/winekit
NTSTATUS
FilterEvtDeviceAdd(
    IN WDFDRIVER        Driver,
    IN PWDFDEVICE_INIT  DeviceInit
    )
/*++
Routine Description:

    EvtDeviceAdd is called by the framework in response to AddDevice
    call from the PnP manager. Here you can query the device properties
    using WdfFdoInitWdmGetPhysicalDevice/IoGetDeviceProperty and based
    on that, decide to create a filter device object and attach to the
    function stack. If you are not interested in filtering this particular
    instance of the device, you can just return STATUS_SUCCESS without creating
    a framework device.

Arguments:

    Driver - Handle to a framework driver object created in DriverEntry

    DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.

Return Value:

    NTSTATUS

--*/
{
    WDF_OBJECT_ATTRIBUTES   deviceAttributes;
    PFILTER_EXTENSION       filterExt;
    NTSTATUS                status;
    WDFDEVICE               device;
    ULONG                   serialNo;
    ULONG                   returnSize;

    PAGED_CODE ();

    UNREFERENCED_PARAMETER(Driver);

    //
    // Get some property of the device you are about to attach and check
    // to see if that's the one you are interested. For demonstration
    // we will get the UINumber of the device. The bus driver reports the
    // serial number as the UINumber.
    //
    status = WdfFdoInitQueryProperty(DeviceInit,
                                  DevicePropertyUINumber,
                                  sizeof(serialNo),
                                  &serialNo,
                                  &returnSize);
    if(!NT_SUCCESS(status)){
        KdPrint(("Failed to get the property of PDO: 0x%p\n", DeviceInit));
    }

    //
    // Tell the framework that you are filter driver. Framework
    // takes care of inherting all the device flags & characterstics
    // from the lower device you are attaching to.
    //
    WdfFdoInitSetFilter(DeviceInit);

    //
    // Specify the size of device extension where we track per device
    // context.
    //

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, FILTER_EXTENSION);

    //
    // We will just register for cleanup notification because we have to
    // delete the control-device when the last instance of the device goes
    // away. If we don't delete, the driver wouldn't get unloaded automatcially
    // by the PNP subsystem.
    //
    deviceAttributes.EvtCleanupCallback = FilterEvtDeviceContextCleanup;

    //
    // Create a framework device object.This call will inturn create
    // a WDM deviceobject, attach to the lower stack and set the
    // appropriate flags and attributes.
    //
    status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
    if (!NT_SUCCESS(status)) {
        KdPrint( ("WdfDeviceCreate failed with status code 0x%x\n", status));
        return status;
    }

    filterExt = FilterGetData(device);
    filterExt->SerialNo = serialNo;

    //
    // Add this device to the FilterDevice collection.
    //
    WdfWaitLockAcquire(FilterDeviceCollectionLock, NULL);
    //
    // WdfCollectionAdd takes a reference on the item object and removes
    // it when you call WdfCollectionRemove.
    //
    status = WdfCollectionAdd(FilterDeviceCollection, device);
    if (!NT_SUCCESS(status)) {
        KdPrint( ("WdfCollectionAdd failed with status code 0x%x\n", status));
    }
    WdfWaitLockRelease(FilterDeviceCollectionLock);

    //
    // Create a control device
    //
    status = FilterCreateControlDevice(device);
    if (!NT_SUCCESS(status)) {
        KdPrint( ("FilterCreateControlDevice failed with status 0x%x\n",
                                status));
        //
        // Let us not fail AddDevice just because we weren't able to create the
        // control device.
        //
        status = STATUS_SUCCESS;
    }

    return status;
}