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;
}
Exemple #3
0
_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;
}