VOID XenUsb_EvtChildListScanForChildren(WDFCHILDLIST child_list) { NTSTATUS status; PXENUSB_DEVICE_DATA xudd = GetXudd(WdfChildListGetDevice(child_list)); XENUSB_PDO_IDENTIFICATION_DESCRIPTION child_description; CHAR path[128]; PCHAR value; ULONG i; FUNCTION_ENTER(); WdfChildListBeginScan(child_list); // hold the queue on each device and set each device to a pending state // read backend/num_ports //RtlStringCbPrintfA(path, ARRAY_SIZE(path), "%s/num-ports", xudd->vectors.backend_path); status = XnReadString(xudd->handle, XBT_NIL, path, &value); if (status != STATUS_SUCCESS) { WdfChildListEndScan(child_list); FUNCTION_MSG("Failed to read num-ports\n"); return; } xudd->num_ports = (ULONG)parse_numeric_string(value); XnFreeMem(xudd->handle, value); FUNCTION_MSG("num-ports = %d\n", xudd->num_ports); for (i = 0; i < 8; i++) { xudd->ports[i].port_number = i + 1; xudd->ports[i].port_type = USB_PORT_TYPE_NOT_CONNECTED; xudd->ports[i].port_status = 0; //1 << PORT_ENABLE; xudd->ports[i].port_change = 0x0000; } /* only a single root hub is enumerated */ WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&child_description.header, sizeof(child_description)); child_description.device_number = 0; //TODO: get the proper index from parent status = WdfChildListAddOrUpdateChildDescriptionAsPresent(child_list, &child_description.header, NULL); if (!NT_SUCCESS(status)) { FUNCTION_MSG("WdfChildListAddOrUpdateChildDescriptionAsPresent failed with status 0x%08x\n", status); } WdfChildListEndScan(child_list); FUNCTION_EXIT(); }
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. Arguments: Returns: STATUS_SUCCESS upon successful removal from the list STATUS_INVALID_PARAMETER if the removal was unsuccessful --*/ { NTSTATUS status; WDFCHILDLIST list; PAGED_CODE (); list = WdfFdoGetDefaultChildList(Device); if (0 == SerialNo) { // // Unplug everybody. We do this by starting a scan and then not reporting // any children upon its completion // status = STATUS_SUCCESS; WdfChildListBeginScan(list); // // A call to WdfChildListBeginScan indicates to the framework that the // driver is about to scan for dynamic children. After this call has // returned, all previously reported children associated with this will be // marked as potentially missing. A call to either // WdfChildListUpdateChildDescriptionAsPresent or // WdfChildListMarkAllChildDescriptionsPresent will mark all previuosly // reported missing children as present. If any children currently // present are not reported present by calling // WdfChildListUpdateChildDescriptionAsPresent at the time of // WdfChildListEndScan, they will be reported as missing to the PnP subsystem // After WdfChildListEndScan call has returned, the framework will // invalidate the device relations for the FDO associated with the list // and report the changes // WdfChildListEndScan(list); } else { PDO_IDENTIFICATION_DESCRIPTION description; WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT( &description.Header, sizeof(description) ); description.SerialNo = SerialNo; // // WdfFdoUpdateChildDescriptionAsMissing indicates to the framework that a // child device that was previuosly detected is no longe present on the bus. // This API can be called by itself or after a call to WdfChildListBeginScan. // After this call has returned, the framework will invalidate the device // relations for the FDO associated with the list and report the changes. // status = WdfChildListUpdateChildDescriptionAsMissing(list, &description.Header); if (status == STATUS_NO_SUCH_DEVICE) { // // serial number didn't exist. Remap it to a status that user // application can understand when it gets translated to win32 // error code. // status = STATUS_INVALID_PARAMETER; } } return status; }
VOID OsrFxEnumerateChildren( _In_ WDFDEVICE Device ) /*++ Routine Description: This routine configures a continuous reader on the interrupt endpoint. Arguments: Return Value: NT status value --*/ { WDFCHILDLIST list; UCHAR i; NTSTATUS status; PDEVICE_CONTEXT pDeviceContext; pDeviceContext = GetDeviceContext(Device); list = WdfFdoGetDefaultChildList(Device); WdfChildListBeginScan(list); // // A call to WdfChildListBeginScan indicates to the framework that the // driver is about to scan for dynamic children. If the driver doesn't // call either WdfChildListUpdateChildDescriptionAsPresent or // WdfChildListMarkAllChildDescriptionsPresent before WdfChildListEndScan is, // called, all the previously reported children will be reported as missing // to the PnP subsystem. // for(i=0; i< RTL_BITS_OF(UCHAR); i++) { // // Report every set bit in the switchstate as a child device. // if(pDeviceContext->CurrentSwitchState & (1<<i)) { PDO_IDENTIFICATION_DESCRIPTION description; // // Initialize the description with the information about the newly // plugged in device. // WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT( &description.Header, sizeof(description) ); // // Since switches are marked in the wrong order on the board, // we will fix it here so that the DM display matches with the // board. // description.SwitchNumber = RTL_BITS_OF(UCHAR)-i; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Switch %d is ON\n", description.SwitchNumber); // // Call the framework to add this child to the devicelist. This call // will internaly call our DescriptionCompare callback to check // whether this device is a new device or existing device. If // it's a new device, the framework will call DescriptionDuplicate to create // a copy of this description in nonpaged pool. // The actual creation of the child device will happen when the framework // receives QUERY_DEVICE_RELATION request from the PNP manager in // response to InvalidateDevice relation call made as part of adding // a new child. // status = WdfChildListAddOrUpdateChildDescriptionAsPresent( list, &description.Header, NULL); // AddressDescription if (status == STATUS_OBJECT_NAME_EXISTS) { } } } WdfChildListEndScan(list); return; }