NTSTATUS DeviceWriteLegacyHardwareKey( _In_ PWSTR PdoName, _In_ PWSTR ComPort, _In_ WDFDEVICE Device ) { WDFKEY key = NULL; NTSTATUS status; UNICODE_STRING pdoString = {0}; UNICODE_STRING comPort = {0}; DECLARE_CONST_UNICODE_STRING(deviceSubkey, SERIAL_DEVICE_MAP); RtlInitUnicodeString(&pdoString, PdoName); RtlInitUnicodeString(&comPort, ComPort); status = WdfDeviceOpenDevicemapKey(Device, &deviceSubkey, KEY_SET_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &key); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "Error: Failed to open DEVICEMAP\\SERIALCOMM key 0x%x", status); goto exit; } status = WdfRegistryAssignUnicodeString(key, &pdoString, &comPort); if (!NT_SUCCESS(status)) { Trace(TRACE_LEVEL_ERROR, "Error: Failed to write to DEVICEMAP\\SERIALCOMM key 0x%x", status); goto exit; } exit: if (key != NULL) { WdfRegistryClose(key); key = NULL; } return status; }
NTSTATUS XenUsb_EvtDriverDeviceAdd(WDFDRIVER driver, PWDFDEVICE_INIT device_init) { NTSTATUS status; WDF_CHILD_LIST_CONFIG child_list_config; WDFDEVICE device; PXENUSB_DEVICE_DATA xudd; //UNICODE_STRING reference; WDF_OBJECT_ATTRIBUTES device_attributes; PNP_BUS_INFORMATION pbi; WDF_PNPPOWER_EVENT_CALLBACKS pnp_power_callbacks; WDF_DEVICE_POWER_CAPABILITIES power_capabilities; WDF_IO_QUEUE_CONFIG queue_config; UCHAR pnp_minor_functions[] = { IRP_MN_QUERY_INTERFACE }; DECLARE_CONST_UNICODE_STRING(symbolicname_name, L"SymbolicName"); WDFSTRING symbolicname_value_wdfstring; WDFKEY device_key; UNICODE_STRING symbolicname_value; UNREFERENCED_PARAMETER(driver); FUNCTION_ENTER(); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_power_callbacks); pnp_power_callbacks.EvtDeviceD0Entry = XenUsb_EvtDeviceD0Entry; pnp_power_callbacks.EvtDeviceD0Exit = XenUsb_EvtDeviceD0Exit; WdfDeviceInitSetPnpPowerEventCallbacks(device_init, &pnp_power_callbacks); status = WdfDeviceInitAssignWdmIrpPreprocessCallback(device_init, XenUsb_EvtDeviceWdmIrpPreprocessQUERY_INTERFACE, IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions)); if (!NT_SUCCESS(status)) { return status; } WdfDeviceInitSetDeviceType(device_init, FILE_DEVICE_BUS_EXTENDER); WdfDeviceInitSetExclusive(device_init, FALSE); WDF_CHILD_LIST_CONFIG_INIT(&child_list_config, sizeof(XENUSB_PDO_IDENTIFICATION_DESCRIPTION), XenUsb_EvtChildListCreateDevice); child_list_config.EvtChildListScanForChildren = XenUsb_EvtChildListScanForChildren; WdfFdoInitSetDefaultChildListConfig(device_init, &child_list_config, WDF_NO_OBJECT_ATTRIBUTES); WdfDeviceInitSetIoType(device_init, WdfDeviceIoBuffered); WdfDeviceInitSetPowerNotPageable(device_init); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&device_attributes, XENUSB_DEVICE_DATA); status = WdfDeviceCreate(&device_init, &device_attributes, &device); if (!NT_SUCCESS(status)) { FUNCTION_MSG("Error creating device %08x\n", status); return status; } xudd = GetXudd(device); xudd->pdo = WdfDeviceWdmGetPhysicalDevice(device); xudd->child_list = WdfFdoGetDefaultChildList(device); KeInitializeEvent(&xudd->backend_event, SynchronizationEvent, FALSE); InitializeListHead(&xudd->partial_pvurb_queue); InitializeListHead(&xudd->partial_pvurb_ring); KeInitializeDpc(&xudd->event_dpc, XenUsb_HandleEventDpc, xudd); KeInitializeSpinLock(&xudd->urb_ring_lock); WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queue_config, WdfIoQueueDispatchParallel); queue_config.PowerManaged = FALSE; /* ? */ queue_config.EvtIoDeviceControl = XenUsb_EvtIoDeviceControl; queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl; queue_config.EvtIoDefault = XenUsb_EvtIoDefault; status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xudd->io_queue); if (!NT_SUCCESS(status)) { FUNCTION_MSG("Error creating io_queue 0x%x\n", status); return status; } WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchParallel); queue_config.PowerManaged = FALSE; /* ? */ //queue_config.EvtIoDeviceControl = XenUsb_EvtIoDeviceControl; queue_config.EvtIoInternalDeviceControl = XenUsb_EvtIoInternalDeviceControl_PVURB; //queue_config.EvtIoDefault = XenUsb_EvtIoDefault; queue_config.Settings.Parallel.NumberOfPresentedRequests = USB_URB_RING_SIZE; /* the queue controls if the ring is full */ status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, &xudd->pvurb_queue); if (!NT_SUCCESS(status)) { FUNCTION_MSG("Error creating urb_queue 0x%x\n", status); return status; } WDF_DEVICE_POWER_CAPABILITIES_INIT(&power_capabilities); power_capabilities.DeviceD1 = WdfTrue; power_capabilities.WakeFromD1 = WdfTrue; power_capabilities.DeviceWake = PowerDeviceD1; power_capabilities.DeviceState[PowerSystemWorking] = PowerDeviceD0; power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1; power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2; power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2; power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3; power_capabilities.DeviceState[PowerSystemShutdown] = PowerDeviceD3; WdfDeviceSetPowerCapabilities(device, &power_capabilities); WdfDeviceSetSpecialFileSupport(device, WdfSpecialFilePaging, TRUE); WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileHibernation, TRUE); WdfDeviceSetSpecialFileSupport(device, WdfSpecialFileDump, TRUE); pbi.BusTypeGuid = GUID_BUS_TYPE_XEN; pbi.LegacyBusType = PNPBus; pbi.BusNumber = 0; WdfDeviceSetBusInformationForChildren(device, &pbi); status = WdfDeviceCreateDeviceInterface(device, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL); if (!NT_SUCCESS(status)) { FUNCTION_MSG("WdfDeviceCreateDeviceInterface returned %08x\n"); return status; } /* USB likes to have a registry key with the symbolic link name in it */ status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &symbolicname_value_wdfstring); if (!NT_SUCCESS(status)) { FUNCTION_MSG("WdfStringCreate returned %08x\n"); return status; } status = WdfDeviceRetrieveDeviceInterfaceString(device, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL, symbolicname_value_wdfstring); if (!NT_SUCCESS(status)) { FUNCTION_MSG("WdfDeviceRetrieveDeviceInterfaceString returned %08x\n"); return status; } WdfStringGetUnicodeString(symbolicname_value_wdfstring, &symbolicname_value); status = WdfDeviceOpenRegistryKey(device, PLUGPLAY_REGKEY_DEVICE, KEY_SET_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &device_key); if (!NT_SUCCESS(status)) { FUNCTION_MSG("WdfDeviceOpenRegistryKey returned %08x\n"); return status; } WdfRegistryAssignUnicodeString(device_key, &symbolicname_name, &symbolicname_value); FUNCTION_EXIT(); return status; }