/** * @brief handles child device processing on device removal. * * @param[in] Device handle to the WDFDEVICE created by FdoEvtDeviceAdd(). * */ VOID RemoveAllChildDevices( IN WDFDEVICE Device) { WdfFdoLockStaticChildListForIteration(Device); WDFDEVICE hChild = NULL; while ((hChild = WdfFdoRetrieveNextStaticChild( Device, hChild, WdfRetrieveAddedChildren)) != NULL) { NTSTATUS Status = WdfPdoMarkMissing(hChild); if (!NT_SUCCESS(Status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, __FUNCTION__": Device %p WdfPdoMarkMissing %p error %x\n", Device, hChild, Status); XXX_TODO("What to do with a pdo we can't mark missing?\n"); } else { TraceEvents(TRACE_LEVEL_WARNING, TRACE_DEVICE, __FUNCTION__": Device %p WdfPdoMarkMissing %p\n", Device, hChild); WDF_DEVICE_STATE deviceState; WDF_DEVICE_STATE_INIT (&deviceState); deviceState.Removed = WdfTrue; WdfDeviceSetDeviceState(hChild, &deviceState); } } WdfFdoUnlockStaticChildListFromIteration(Device); }
NTSTATUS Bus_UnPlugDevice( WDFDEVICE Device, ULONG SerialNo ) /*++ Routine Description: The application has told us a device has departed from the bus. We therefore need to flag the PDO as no longer present and then tell Plug and Play about it. Arguments: Returns: STATUS_SUCCESS upon successful removal from the list STATUS_INVALID_PARAMETER if the removal was unsuccessful --*/ { PPDO_DEVICE_DATA pdoData; BOOLEAN found = FALSE; BOOLEAN plugOutAll; WDFDEVICE hChild; NTSTATUS status = STATUS_INVALID_PARAMETER; PAGED_CODE (); plugOutAll = (0 == SerialNo) ? TRUE : FALSE; hChild = NULL; WdfFdoLockStaticChildListForIteration(Device); while ((hChild = WdfFdoRetrieveNextStaticChild(Device, hChild, WdfRetrieveAddedChildren)) != NULL) { if (plugOutAll) { status = WdfPdoMarkMissing(hChild); if(!NT_SUCCESS(status)) { KdPrint(("WdfPdoMarkMissing failed 0x%x\n", status)); break; } found = TRUE; } else { pdoData = PdoGetData(hChild); if (SerialNo == pdoData->SerialNo) { status = WdfPdoMarkMissing(hChild); if(!NT_SUCCESS(status)) { KdPrint(("WdfPdoMarkMissing failed 0x%x\n", status)); break; } found = TRUE; break; } } } WdfFdoUnlockStaticChildListFromIteration(Device); if (found) { status = STATUS_SUCCESS; } return status; }