NTSTATUS Ds4_PreparePdo(PWDFDEVICE_INIT DeviceInit, PUNICODE_STRING DeviceId, PUNICODE_STRING DeviceDescription) { NTSTATUS status; UNICODE_STRING buffer; // prepare device description status = RtlUnicodeStringInit(DeviceDescription, L"Virtual DualShock 4 Controller"); if (!NT_SUCCESS(status)) return status; // Set hardware IDs RtlUnicodeStringInit(&buffer, L"USB\\VID_054C&PID_05C4&REV_0100"); status = WdfPdoInitAddHardwareID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; RtlUnicodeStringCopy(DeviceId, &buffer); RtlUnicodeStringInit(&buffer, L"USB\\VID_054C&PID_05C4"); status = WdfPdoInitAddHardwareID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; // Set compatible IDs RtlUnicodeStringInit(&buffer, L"USB\\Class_03&SubClass_00&Prot_00"); status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; RtlUnicodeStringInit(&buffer, L"USB\\Class_03&SubClass_00"); status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; RtlUnicodeStringInit(&buffer, L"USB\\Class_03"); status = WdfPdoInitAddCompatibleID(DeviceInit, &buffer); if (!NT_SUCCESS(status)) return status; return STATUS_SUCCESS; }
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; }