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 and set Opened to FALSE to match // the state change (in the case of a surprise removal of the target, // ToastMon_EvtIoTargetQueryRemove is not called so Opened is still TRUE). // WdfWaitLockAcquire(deviceExtension->TargetDeviceCollectionLock, NULL); WdfCollectionRemove(deviceExtension->TargetDeviceCollection, IoTarget); targetDeviceInfo->Opened = FALSE; WdfWaitLockRelease(deviceExtension->TargetDeviceCollectionLock); // // Finally delete the target. // WdfObjectDelete(IoTarget); return; }
VOID FilterEvtDeviceContextCleanup( IN WDFDEVICE Device ) /*++ Routine Description: EvtDeviceRemove event callback must perform any operations that are necessary before the specified device is removed. The framework calls the driver's EvtDeviceRemove callback when the PnP manager sends an IRP_MN_REMOVE_DEVICE request to the driver stack. Arguments: Device - Handle to a framework device object. Return Value: WDF status code --*/ { ULONG count; PAGED_CODE(); KdPrint(("Entered FilterEvtDeviceContextCleanup\n")); WdfWaitLockAcquire(FilterDeviceCollectionLock, NULL); count = WdfCollectionGetCount(FilterDeviceCollection); if(count == 1) { // // We are the last instance. So let us delete the control-device // so that driver can unload when the FilterDevice is deleted. // We absolutely have to do the deletion of control device with // the collection lock acquired because we implicitly use this // lock to protect ControlDevice global variable. We need to make // sure another thread doesn't attempt to create while we are // deleting the device. // FilterDeleteControlDevice(Device); } WdfCollectionRemove(FilterDeviceCollection, Device); WdfWaitLockRelease(FilterDeviceCollectionLock); }
/** * @brief Allocate a workitem from or for our collection of workitems. * Must be called with the device lock held. * * @param[in] Device handle to the WDFDEVICE created by FdoEvtDeviceAdd. * @param[in] callback only optional if this is add device doing an allocation! * @param[in] Param0 arbitrary context data * @param[in] Param1 arbitrary context data * @param[in] Param2 arbitrary context data * @param[in] Param3 arbitrary context data * * @returns a WDFWORKITEM handle or NULL on failure. * */ WDFWORKITEM NewWorkItem( IN PUSB_FDO_CONTEXT fdoContext, IN PFN_WDF_WORKITEM callback, IN ULONG_PTR Param0, IN ULONG_PTR Param1, IN ULONG_PTR Param2, IN ULONG_PTR Param3) { // // First try to get a workitem from our collection of them. // WDFWORKITEM WorkItem = (WDFWORKITEM) WdfCollectionGetFirstItem(fdoContext->FreeWorkItems); if (WorkItem == NULL) { // // ok - allocate a new one. // TraceEvents(TRACE_LEVEL_VERBOSE, TRACE_DEVICE, __FUNCTION__": Device %p FreeWorkItems is empty, init count %d\n", fdoContext->WdfDevice, INIT_WORK_ITEM_COUNT); NTSTATUS status = STATUS_SUCCESS; WDF_OBJECT_ATTRIBUTES attributes; WDF_WORKITEM_CONFIG workitemConfig; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE( &attributes, USB_FDO_WORK_ITEM_CONTEXT); attributes.ParentObject = fdoContext->WdfDevice; WDF_WORKITEM_CONFIG_INIT( &workitemConfig, EvtFdoDeviceGenericWorkItem); status = WdfWorkItemCreate( &workitemConfig, &attributes, &WorkItem); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": WdfWorkItemCreate error %x\n", status); return NULL; } } else { // note that WdfCollectionGetFirstItem doesn't remove it from the collection. WdfCollectionRemove(fdoContext->FreeWorkItems, WorkItem); } if (WorkItem) { // initialize it. PUSB_FDO_WORK_ITEM_CONTEXT context = WorkItemGetContext(WorkItem); context->FdoContext = fdoContext; context->CallBack = callback; context->Params[0] = Param0; context->Params[1] = Param1; context->Params[2] = Param2; context->Params[3] = Param3; } return WorkItem; }