BOOLEAN FxPkgPnp::PnpCheckAndIncrementRestartCount( VOID ) /*++ Routine Description: This is a mode-dependent wrapper for PnpIncrementRestartCountLogic, which determines if this device should ask the bus driver to reenumerate the device. Please refer to PnpIncrementRestartCountLogic's comment block for more information. Arguments: None Return Value: TRUE if a restart should be requested. --*/ { HRESULT hr; FxAutoRegKey restart; FxDevice* device; IWudfDeviceStack* deviceStack; WDF_PROPERTY_STORE_ROOT propertyStore; WDF_PROPERTY_STORE_DISPOSITION disposition; device = GetDevice(); deviceStack = device->GetDeviceStack(); propertyStore.LengthCb = sizeof(WDF_PROPERTY_STORE_ROOT); propertyStore.RootClass = WdfPropertyStoreRootClassHardwareKey; propertyStore.Qualifier.HardwareKey.ServiceName = L"WudfDiagnostics"; hr = deviceStack->CreateRegistryEntry(&propertyStore, WdfPropertyStoreCreateVolatile, KEY_QUERY_VALUE | KEY_SET_VALUE, L"Restart", (HKEY*)&restart.m_Key, &disposition); if (FAILED(hr)) { return FALSE; } return PnpIncrementRestartCountLogic(restart.m_Key, disposition == CreatedNewStore); }
NTSTATUS FxDriver::OpenParametersKey( VOID ) { HRESULT hr; NTSTATUS status; PFX_DRIVER_GLOBALS FxDriverGlobals = GetDriverGlobals(); PDRIVER_OBJECT_UM pDrvObj = GetDriverObject(); IWudfDeviceStack* pDevStack = (IWudfDeviceStack*)pDrvObj->WudfDevStack; UMINT::WDF_PROPERTY_STORE_ROOT rootSpecifier; UMINT::WDF_PROPERTY_STORE_RETRIEVE_FLAGS flags; CANSI_STRING serviceNameA; DECLARE_UNICODE_STRING_SIZE(serviceNameW, WDF_DRIVER_GLOBALS_NAME_LEN); HKEY hKey; RtlInitAnsiString(&serviceNameA, FxDriverGlobals->Public.DriverName); status = RtlAnsiStringToUnicodeString(&serviceNameW, &serviceNameA, FALSE); if (NT_SUCCESS(status)) { rootSpecifier.LengthCb = sizeof(UMINT::WDF_PROPERTY_STORE_ROOT); rootSpecifier.RootClass = UMINT::WdfPropertyStoreRootDriverParametersKey; rootSpecifier.Qualifier.ParametersKey.ServiceName = serviceNameW.Buffer; flags = UMINT::WdfPropertyStoreCreateIfMissing; hr = pDevStack->CreateRegistryEntry(&rootSpecifier, flags, GENERIC_ALL & ~(GENERIC_WRITE | KEY_CREATE_SUB_KEY | WRITE_DAC), NULL, &hKey, NULL); status = FxDevice::NtStatusFromHr(pDevStack, hr); if (NT_SUCCESS(status)) { m_DriverParametersKey = hKey; } } return status; }
_Must_inspect_result_ NTSTATUS FxUsbDevice::InitDevice( __in ULONG USBDClientContractVersionForWdfClient ) { HRESULT hr = S_OK; NTSTATUS status = STATUS_SUCCESS; IWudfDevice* device = NULL; IWudfDeviceStack* devstack = NULL; UMURB urb; USB_CONFIGURATION_DESCRIPTOR config; USHORT wTotalLength = 0; FxRequestBuffer buf; FxUsbDeviceControlContext context(FxUrbTypeLegacy); WDF_USB_CONTROL_SETUP_PACKET setupPacket; USHORT deviceStatus = 0; UCHAR deviceSpeed = 0; FxSyncRequest request(GetDriverGlobals(), NULL); FxSyncRequest request2(GetDriverGlobals(), &context); UNREFERENCED_PARAMETER(USBDClientContractVersionForWdfClient); status = request.Initialize(); if (!NT_SUCCESS(status)) { DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Failed to initialize FxSyncRequest"); goto Done; } status = request2.Initialize(); if (!NT_SUCCESS(status)) { DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Failed to initialize second FxSyncRequest"); goto Done; } status = request.m_TrueRequest->ValidateTarget(this); if (!NT_SUCCESS(status)) { DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Failed to validate FxSyncRequest target"); goto Done; } status = request2.m_TrueRequest->ValidateTarget(this); if (!NT_SUCCESS(status)) { DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Failed to validate second FxSyncRequest target"); goto Done; } RtlZeroMemory(&urb, sizeof(urb)); device = m_DeviceBase->GetDeviceObject(); devstack = device->GetDeviceStackInterface(); if (m_pHostTargetFile == NULL) { hr = devstack->CreateWdfFile(device, device->GetAttachedDevice(), NULL, &m_pHostTargetFile); if (SUCCEEDED(hr)) { m_WinUsbHandle = (WINUSB_INTERFACE_HANDLE)m_pHostTargetFile->GetCreateContext(); } } // // Get USB device descriptor // FxUsbUmInitDescriptorUrb(&urb, m_WinUsbHandle, USB_DEVICE_DESCRIPTOR_TYPE, sizeof(m_DeviceDescriptor), &m_DeviceDescriptor); FxUsbUmFormatRequest(request.m_TrueRequest, &urb.UmUrbHeader, m_pHostTargetFile, TRUE); status = SendSyncRequest(&request, 5); if (!NT_SUCCESS(status)) { goto Done; } // // Get USB configuration descriptor // FxUsbUmInitDescriptorUrb(&urb, m_WinUsbHandle, USB_CONFIGURATION_DESCRIPTOR_TYPE, sizeof(config), &config); FxUsbUmFormatRequest(request.m_TrueRequest, &urb.UmUrbHeader, m_pHostTargetFile, TRUE); status = SendSyncRequest(&request, 5); if (!NT_SUCCESS(status)) { goto Done; } if (config.wTotalLength < sizeof(USB_CONFIGURATION_DESCRIPTOR)) { // // Not enough info returned // status = STATUS_UNSUCCESSFUL; DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Could not retrieve config descriptor size, config.wTotalLength %d < " "sizeof(config descriptor) (%d), %!STATUS!", config.wTotalLength, sizeof(USB_CONFIGURATION_DESCRIPTOR), status); goto Done; } wTotalLength = config.wTotalLength; m_ConfigDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR) FxPoolAllocate(GetDriverGlobals(), NonPagedPool, wTotalLength); if (NULL == m_ConfigDescriptor) { status = STATUS_INSUFFICIENT_RESOURCES; DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Could not allocate %d bytes for config descriptor, %!STATUS!", sizeof(USB_CONFIGURATION_DESCRIPTOR), status); goto Done; } // // Get USB configuration descriptor and subsequent interface descriptors, etc. // FxUsbUmInitDescriptorUrb(&urb, m_WinUsbHandle, USB_CONFIGURATION_DESCRIPTOR_TYPE, wTotalLength, m_ConfigDescriptor); FxUsbUmFormatRequest(request.m_TrueRequest, &urb.UmUrbHeader, m_pHostTargetFile, TRUE); status = SendSyncRequest(&request, 5); if (!NT_SUCCESS(status)) { goto Done; } else if (m_ConfigDescriptor->wTotalLength != wTotalLength) { // // Invalid wTotalLength // status = STATUS_DEVICE_DATA_ERROR; DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Defective USB device reported two different config descriptor " "wTotalLength values: %d and %d, %!STATUS!", wTotalLength, m_ConfigDescriptor->wTotalLength, status); goto Done; } m_NumInterfaces = m_ConfigDescriptor->bNumInterfaces; // // Check to see if we are wait wake capable // if (m_ConfigDescriptor->bmAttributes & USB_CONFIG_REMOTE_WAKEUP) { m_Traits |= WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE; } // // Get the device status to check if device is self-powered. // WDF_USB_CONTROL_SETUP_PACKET_INIT_GET_STATUS(&setupPacket, BmRequestToDevice, 0); // Device status buf.SetBuffer(&deviceStatus, sizeof(USHORT)); status = FormatControlRequest(request2.m_TrueRequest, &setupPacket, &buf); if (!NT_SUCCESS(status)) { goto Done; } status = SendSyncRequest(&request2, 5); if (!NT_SUCCESS(status)) { goto Done; } if (deviceStatus & USB_GETSTATUS_SELF_POWERED) { m_Traits |= WDF_USB_DEVICE_TRAIT_SELF_POWERED; } // // Get device speed information. // FxUsbUmInitInformationUrb(&urb, m_WinUsbHandle, sizeof(UCHAR), &deviceSpeed); FxUsbUmFormatRequest(request.m_TrueRequest, &urb.UmUrbHeader, m_pHostTargetFile, TRUE); status = SendSyncRequest(&request, 5); if (!NT_SUCCESS(status)) { goto Done; } if (deviceSpeed == 3) { m_Traits |= WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED; } // // User-mode events must be initialized manually. // status = m_InterfaceIterationLock.Initialize(); if (!NT_SUCCESS(status)) { goto Done; } Done: return status; }