NTSTATUS XenPci_EvtChildListCreateDevice(WDFCHILDLIST child_list, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER identification_header, PWDFDEVICE_INIT child_init) { NTSTATUS status = STATUS_SUCCESS; WDF_OBJECT_ATTRIBUTES child_attributes; WDFDEVICE child_device; PXENPCI_PDO_IDENTIFICATION_DESCRIPTION identification = (PXENPCI_PDO_IDENTIFICATION_DESCRIPTION)identification_header; WDF_DEVICE_PNP_CAPABILITIES child_pnp_capabilities; DECLARE_UNICODE_STRING_SIZE(buffer, 512); DECLARE_CONST_UNICODE_STRING(location, L"Xen Bus"); PXENPCI_PDO_DEVICE_DATA xppdd; PXENPCI_DEVICE_DATA xpdd = GetXpdd(WdfChildListGetDevice(child_list)); //WDF_PDO_EVENT_CALLBACKS pdo_callbacks; WDF_PNPPOWER_EVENT_CALLBACKS child_pnp_power_callbacks; //UCHAR pnp_minor_functions[] = { IRP_MN_START_DEVICE }; WDF_DEVICE_POWER_CAPABILITIES child_power_capabilities; FUNCTION_ENTER(); WdfDeviceInitSetDeviceType(child_init, FILE_DEVICE_UNKNOWN); WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&child_pnp_power_callbacks); child_pnp_power_callbacks.EvtDeviceD0Entry = XenPciPdo_EvtDeviceD0Entry; child_pnp_power_callbacks.EvtDeviceD0Exit = XenPciPdo_EvtDeviceD0Exit; child_pnp_power_callbacks.EvtDeviceUsageNotification = XenPciPdo_EvtDeviceUsageNotification; WdfDeviceInitSetPnpPowerEventCallbacks(child_init, &child_pnp_power_callbacks); FUNCTION_MSG("device = '%s', index = '%d', path = '%s'\n", identification->device, identification->index, identification->path); //status = WdfDeviceInitAssignWdmIrpPreprocessCallback(child_init, XenPciPdo_EvtDeviceWdmIrpPreprocess_START_DEVICE, // IRP_MJ_PNP, pnp_minor_functions, ARRAY_SIZE(pnp_minor_functions)); //if (!NT_SUCCESS(status)) { // return status; //} //WDF_PDO_EVENT_CALLBACKS_INIT(&pdo_callbacks); //pdo_callbacks.EvtDeviceResourcesQuery = XenPciPdo_EvtDeviceResourcesQuery; //pdo_callbacks.EvtDeviceResourceRequirementsQuery = XenPciPdo_EvtDeviceResourceRequirementsQuery; //pdo_callbacks.EvtDeviceEject = XenPciPdo_EvtDeviceEject; //pdo_callbacks.EvtDeviceSetLock = XenPciPdo_EvtDeviceSetLock; //WdfPdoInitSetEventCallbacks(child_init, &pdo_callbacks); RtlUnicodeStringPrintf(&buffer, L"xen\\%S", identification->device); status = WdfPdoInitAssignDeviceID(child_init, &buffer); if (!NT_SUCCESS(status)) { return status; } status = WdfPdoInitAddHardwareID(child_init, &buffer); if (!NT_SUCCESS(status)) { return status; } status = WdfPdoInitAddCompatibleID(child_init, &buffer); if (!NT_SUCCESS(status)) { return status; } RtlUnicodeStringPrintf(&buffer, L"%02d", identification->index); status = WdfPdoInitAssignInstanceID(child_init, &buffer); if (!NT_SUCCESS(status)) { return status; } RtlUnicodeStringPrintf(&buffer, L"Xen %S device #%d", identification->device, identification->index); status = WdfPdoInitAddDeviceText(child_init, &buffer, &location, 0x0409); if (!NT_SUCCESS(status)) { return status; } WdfPdoInitSetDefaultLocale(child_init, 0x0409); WdfDeviceInitSetPowerNotPageable(child_init); WdfDeviceInitRegisterPnpStateChangeCallback(child_init, WdfDevStatePnpQueryCanceled, XenPci_EvtDevicePnpStateChange, StateNotificationEnterState); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&child_attributes, XENPCI_PDO_DEVICE_DATA); status = WdfDeviceCreate(&child_init, &child_attributes, &child_device); if (!NT_SUCCESS(status)) { return status; } xppdd = GetXppdd(child_device); xppdd->wdf_device = child_device; xppdd->wdf_device_bus_fdo = WdfChildListGetDevice(child_list); xppdd->xpdd = xpdd; WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFilePaging, TRUE); WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileHibernation, TRUE); WdfDeviceSetSpecialFileSupport(child_device, WdfSpecialFileDump, TRUE); WDF_DEVICE_PNP_CAPABILITIES_INIT(&child_pnp_capabilities); child_pnp_capabilities.LockSupported = WdfFalse; child_pnp_capabilities.EjectSupported = WdfTrue; child_pnp_capabilities.Removable = WdfTrue; child_pnp_capabilities.DockDevice = WdfFalse; child_pnp_capabilities.UniqueID = WdfFalse; child_pnp_capabilities.SilentInstall = WdfTrue; child_pnp_capabilities.SurpriseRemovalOK = WdfTrue; child_pnp_capabilities.HardwareDisabled = WdfFalse; WdfDeviceSetPnpCapabilities(child_device, &child_pnp_capabilities); WDF_DEVICE_POWER_CAPABILITIES_INIT(&child_power_capabilities); child_power_capabilities.DeviceD1 = WdfTrue; child_power_capabilities.WakeFromD1 = WdfTrue; child_power_capabilities.DeviceWake = PowerDeviceD1; child_power_capabilities.DeviceState[PowerSystemWorking] = PowerDeviceD0; child_power_capabilities.DeviceState[PowerSystemSleeping1] = PowerDeviceD1; child_power_capabilities.DeviceState[PowerSystemSleeping2] = PowerDeviceD2; child_power_capabilities.DeviceState[PowerSystemSleeping3] = PowerDeviceD2; child_power_capabilities.DeviceState[PowerSystemHibernate] = PowerDeviceD3; child_power_capabilities.DeviceState[PowerSystemShutdown] = PowerDeviceD3; WdfDeviceSetPowerCapabilities(child_device, &child_power_capabilities); RtlStringCbCopyA(xppdd->path, ARRAY_SIZE(xppdd->path), identification->path); RtlStringCbCopyA(xppdd->device, ARRAY_SIZE(xppdd->device), identification->device); xppdd->index = identification->index; KeInitializeEvent(&xppdd->backend_state_event, SynchronizationEvent, FALSE); ExInitializeFastMutex(&xppdd->backend_state_mutex); xppdd->backend_state = XenbusStateUnknown; xppdd->frontend_state = XenbusStateUnknown; xppdd->backend_path[0] = '\0'; xppdd->backend_id = 0; FUNCTION_EXIT(); 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; }
NTSTATUS TpmEvtDeviceAdd( IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit ) { NTSTATUS status = STATUS_SUCCESS; WDF_PNPPOWER_EVENT_CALLBACKS PnpPowerEventCallbacks; WDF_OBJECT_ATTRIBUTES DeviceAttributes; WDFDEVICE device; PTPM_CONTEXT TpmContext; WDF_IO_QUEUE_CONFIG IoQueueConfig; WDFQUEUE hQueue; WDF_QUERY_INTERFACE_CONFIG InterfaceConfig; TPM_INTERFACE_STANDARD TpmInterface; WDF_DEVICE_POWER_CAPABILITIES PowerCaps; PAGED_CODE(); UNREFERENCED_PARAMETER( Driver ); RtlZeroMemory(&PnpPowerEventCallbacks,sizeof(PnpPowerEventCallbacks)); RtlZeroMemory(&PowerCaps,sizeof(PowerCaps)); KdPrintEx((DPFLTR_PNPMEM_ID, DPFLTR_INFO_LEVEL, "TpmEvtDeviceAdd routine PDO: %p (%p)\n", WdfDriverWdmGetDriverObject(Driver))); // // Zero out the PnpPowerCallbacks structure. // WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&PnpPowerEventCallbacks); // // These two callbacks set up and tear down hardware state that must be // done every time the device moves in and out of the D0-working state. // PnpPowerEventCallbacks.EvtDeviceD0Entry = TpmEvtDeviceD0Entry; PnpPowerEventCallbacks.EvtDeviceD0Exit = TpmEvtDeviceD0Exit; // // Set Callbacks for any of the functions we are interested in. // If no callback is set, Framework will take the default action // by itself. // PnpPowerEventCallbacks.EvtDevicePrepareHardware = TpmEvtDevicePrepareHardware; PnpPowerEventCallbacks.EvtDeviceReleaseHardware = TpmEvtDeviceReleaseHardware; WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit,&PnpPowerEventCallbacks); // // Specify the context type and size for the device we are about to create. // RtlZeroMemory(&DeviceAttributes,sizeof(DeviceAttributes)); WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&DeviceAttributes, TPM_CONTEXT); DeviceAttributes.Size = sizeof(WDF_OBJECT_ATTRIBUTES); DeviceAttributes.SynchronizationScope = WdfSynchronizationScopeInheritFromParent; DeviceAttributes.ExecutionLevel = WdfExecutionLevelPassive; status = WdfDeviceCreate(&DeviceInit,&DeviceAttributes,&device); if(NT_SUCCESS(status)) { TpmContext = GetTpmContext(device); RtlZeroMemory(TpmContext,sizeof(TPM_CONTEXT)); TpmContext->Device = device; TpmContext->AccessRegister = FALSE; KeInitializeSpinLock(&TpmContext->SpinLock); TpmContext->TpmState = StSuspend; TpmInitStateTable(); KeInitializeEvent(&TpmContext->Event,NotificationEvent,TRUE); status = WdfDeviceCreateDeviceInterface(device,&GUID_DEVINTERFACE_TPM,NULL); if(NT_SUCCESS(status)) { WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE( &IoQueueConfig, WdfIoQueueDispatchParallel ); IoQueueConfig.EvtIoDeviceControl = TpmEvtIoDeviceControl; status = WdfIoQueueCreate( device, &IoQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &hQueue ); if(NT_SUCCESS(status)) { WDF_DEVICE_POWER_CAPABILITIES_INIT(&PowerCaps); WdfDeviceSetPowerCapabilities(device,&PowerCaps); // TpmGetRegistryFlags(device,TpmContext); // RtlZeroMemory(&TpmInterface,sizeof(TpmInterface)); TpmInterface.InterfaceHeader.Size = sizeof(TpmInterface); TpmInterface.InterfaceHeader.Version = 1; TpmInterface.InterfaceHeader.Context = (PVOID)TpmContext; TpmInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp; TpmInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp; TpmInterface.pfn_TpmSetMorBitState = TpmSetMorBitState; // // Initialize the InterfaceConfig structure. // WDF_QUERY_INTERFACE_CONFIG_INIT( &InterfaceConfig, (PINTERFACE)&TpmInterface, &GUID_TPM_INTERFACE_STANDARD, NULL ); // // Create the interface. // status = WdfDeviceAddQueryInterface( device, &InterfaceConfig ); if(!NT_SUCCESS(status)) { KdPrintEx((DPFLTR_PNPMEM_ID, DPFLTR_INFO_LEVEL, "WdfDeviceAddQueryInterface failed with NTSTATUS 0x%x\n",status)); } } else { KdPrintEx((DPFLTR_PNPMEM_ID, DPFLTR_INFO_LEVEL, "WdfIoQueueCreate failed with Status code 0x%x\n",status)); } } else { KdPrintEx((DPFLTR_PNPMEM_ID, DPFLTR_INFO_LEVEL, "WdfDeviceCreateDeviceInterface failed with Status code 0x%x\n",status)); } } else { KdPrintEx((DPFLTR_PNPMEM_ID, DPFLTR_INFO_LEVEL, "WdfDeviceCreate failed with Status code 0x%x\n",status)); } KdPrintEx((DPFLTR_PNPMEM_ID, DPFLTR_INFO_LEVEL, "TpmEvtDeviceAdd exited with Status code 0x%x\n",status)); return status; }