18a978a17SVictor Perevertkin /*++
28a978a17SVictor Perevertkin
38a978a17SVictor Perevertkin Copyright (c) Microsoft Corporation
48a978a17SVictor Perevertkin
58a978a17SVictor Perevertkin Module Name:
68a978a17SVictor Perevertkin
78a978a17SVictor Perevertkin FxUsbDeviceKm.cpp
88a978a17SVictor Perevertkin
98a978a17SVictor Perevertkin Abstract:
108a978a17SVictor Perevertkin
118a978a17SVictor Perevertkin Author:
128a978a17SVictor Perevertkin
138a978a17SVictor Perevertkin Environment:
148a978a17SVictor Perevertkin
158a978a17SVictor Perevertkin kernel mode only
168a978a17SVictor Perevertkin
178a978a17SVictor Perevertkin Revision History:
188a978a17SVictor Perevertkin
198a978a17SVictor Perevertkin --*/
208a978a17SVictor Perevertkin
218a978a17SVictor Perevertkin extern "C" {
228a978a17SVictor Perevertkin #include <initguid.h>
238a978a17SVictor Perevertkin }
248a978a17SVictor Perevertkin
258a978a17SVictor Perevertkin #include "fxusbpch.hpp"
268a978a17SVictor Perevertkin
278a978a17SVictor Perevertkin
288a978a17SVictor Perevertkin extern "C" {
298a978a17SVictor Perevertkin #include "FxUsbDeviceKm.tmh"
308a978a17SVictor Perevertkin }
318a978a17SVictor Perevertkin
328a978a17SVictor Perevertkin
338a978a17SVictor Perevertkin
348a978a17SVictor Perevertkin
358a978a17SVictor Perevertkin
368a978a17SVictor Perevertkin
378a978a17SVictor Perevertkin
388a978a17SVictor Perevertkin #define UCHAR_MAX (0xff)
398a978a17SVictor Perevertkin
408a978a17SVictor Perevertkin
418a978a17SVictor Perevertkin _Must_inspect_result_
428a978a17SVictor Perevertkin NTSTATUS
InitDevice(__in ULONG USBDClientContractVersionForWdfClient)438a978a17SVictor Perevertkin FxUsbDevice::InitDevice(
448a978a17SVictor Perevertkin __in ULONG USBDClientContractVersionForWdfClient
458a978a17SVictor Perevertkin )
468a978a17SVictor Perevertkin {
478a978a17SVictor Perevertkin URB urb;
488a978a17SVictor Perevertkin FxSyncRequest request(GetDriverGlobals(), NULL);
498a978a17SVictor Perevertkin WDF_REQUEST_SEND_OPTIONS options;
508a978a17SVictor Perevertkin NTSTATUS status;
518a978a17SVictor Perevertkin ULONG size;
528a978a17SVictor Perevertkin
538a978a17SVictor Perevertkin RtlZeroMemory(&urb, sizeof(urb));
548a978a17SVictor Perevertkin
558a978a17SVictor Perevertkin if (USBDClientContractVersionForWdfClient != USBD_CLIENT_CONTRACT_VERSION_INVALID) {
568a978a17SVictor Perevertkin
578a978a17SVictor Perevertkin //
588a978a17SVictor Perevertkin // Register with USBDEX.lib
598a978a17SVictor Perevertkin //
608a978a17SVictor Perevertkin status = USBD_CreateHandle(m_InStackDevice,
618a978a17SVictor Perevertkin m_TargetDevice,
628a978a17SVictor Perevertkin USBDClientContractVersionForWdfClient,
638a978a17SVictor Perevertkin GetDriverGlobals()->Tag,
648a978a17SVictor Perevertkin &m_USBDHandle);
658a978a17SVictor Perevertkin
668a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
678a978a17SVictor Perevertkin DoTraceLevelMessage(
688a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
698a978a17SVictor Perevertkin "USBD_CreateHandle failed, %!STATUS!", status);
708a978a17SVictor Perevertkin goto Done;
718a978a17SVictor Perevertkin }
728a978a17SVictor Perevertkin
738a978a17SVictor Perevertkin m_UrbType = FxUrbTypeUsbdAllocated;
748a978a17SVictor Perevertkin }
758a978a17SVictor Perevertkin
768a978a17SVictor Perevertkin status = request.m_TrueRequest->ValidateTarget(this);
778a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
788a978a17SVictor Perevertkin goto Done;
798a978a17SVictor Perevertkin }
808a978a17SVictor Perevertkin
818a978a17SVictor Perevertkin UsbBuildGetDescriptorRequest(&urb,
828a978a17SVictor Perevertkin sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
838a978a17SVictor Perevertkin USB_DEVICE_DESCRIPTOR_TYPE,
848a978a17SVictor Perevertkin 0,
858a978a17SVictor Perevertkin 0,
868a978a17SVictor Perevertkin &m_DeviceDescriptor,
878a978a17SVictor Perevertkin NULL,
888a978a17SVictor Perevertkin sizeof(m_DeviceDescriptor),
898a978a17SVictor Perevertkin NULL);
908a978a17SVictor Perevertkin
918a978a17SVictor Perevertkin FxFormatUsbRequest(request.m_TrueRequest, &urb, FxUrbTypeLegacy, NULL);
928a978a17SVictor Perevertkin
938a978a17SVictor Perevertkin WDF_REQUEST_SEND_OPTIONS_INIT(&options, 0);
948a978a17SVictor Perevertkin WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&options, WDF_REL_TIMEOUT_IN_SEC(5));
958a978a17SVictor Perevertkin
968a978a17SVictor Perevertkin status = SubmitSync(request.m_TrueRequest, &options);
978a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
988a978a17SVictor Perevertkin DoTraceLevelMessage(
998a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
1008a978a17SVictor Perevertkin "Could not retrieve device descriptor, %!STATUS!", status);
1018a978a17SVictor Perevertkin goto Done;
1028a978a17SVictor Perevertkin }
1038a978a17SVictor Perevertkin
1048a978a17SVictor Perevertkin //
1058a978a17SVictor Perevertkin // After successfully completing any default control URB, USBD/usbport fills
1068a978a17SVictor Perevertkin // in the PipeHandle field of the URB (it is the same offset in every URB,
1078a978a17SVictor Perevertkin // which this CASSERT verifies. Since USBD_DEFAULT_PIPE_TRANSFER is not
1088a978a17SVictor Perevertkin // supported by USBD (it is by USBPORT), this is the prescribed way of getting
1098a978a17SVictor Perevertkin // the default control pipe so that you can set the PipeHandle field in
1108a978a17SVictor Perevertkin // _URB_CONTROL_TRANSFER.
1118a978a17SVictor Perevertkin //
1128a978a17SVictor Perevertkin WDFCASSERT(FIELD_OFFSET(_URB_CONTROL_TRANSFER, PipeHandle) ==
1138a978a17SVictor Perevertkin FIELD_OFFSET(_URB_CONTROL_DESCRIPTOR_REQUEST, Reserved));
1148a978a17SVictor Perevertkin
1158a978a17SVictor Perevertkin m_ControlPipe = urb.UrbControlDescriptorRequest.Reserved;
1168a978a17SVictor Perevertkin
1178a978a17SVictor Perevertkin USB_CONFIGURATION_DESCRIPTOR config;
1188a978a17SVictor Perevertkin
1198a978a17SVictor Perevertkin RtlZeroMemory(&config, sizeof(config));
1208a978a17SVictor Perevertkin size = sizeof(config);
1218a978a17SVictor Perevertkin
1228a978a17SVictor Perevertkin UsbBuildGetDescriptorRequest(&urb,
1238a978a17SVictor Perevertkin sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST),
1248a978a17SVictor Perevertkin USB_CONFIGURATION_DESCRIPTOR_TYPE,
1258a978a17SVictor Perevertkin 0,
1268a978a17SVictor Perevertkin 0,
1278a978a17SVictor Perevertkin &config,
1288a978a17SVictor Perevertkin NULL,
1298a978a17SVictor Perevertkin size,
1308a978a17SVictor Perevertkin NULL);
1318a978a17SVictor Perevertkin
1328a978a17SVictor Perevertkin request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_SUCCESS);
1338a978a17SVictor Perevertkin request.m_TrueRequest->ClearFieldsForReuse();
1348a978a17SVictor Perevertkin FxFormatUsbRequest(request.m_TrueRequest, &urb, FxUrbTypeLegacy, NULL);
1358a978a17SVictor Perevertkin
1368a978a17SVictor Perevertkin status = SubmitSync(request.m_TrueRequest, &options);
1378a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
1388a978a17SVictor Perevertkin DoTraceLevelMessage(
1398a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
1408a978a17SVictor Perevertkin "Could not retrieve config descriptor size, %!STATUS!", status);
1418a978a17SVictor Perevertkin goto Done;
1428a978a17SVictor Perevertkin }
1438a978a17SVictor Perevertkin else if (urb.UrbControlDescriptorRequest.TransferBufferLength == 0) {
1448a978a17SVictor Perevertkin //
1458a978a17SVictor Perevertkin // Not enough info returned
1468a978a17SVictor Perevertkin //
1478a978a17SVictor Perevertkin status = STATUS_UNSUCCESSFUL;
1488a978a17SVictor Perevertkin
1498a978a17SVictor Perevertkin DoTraceLevelMessage(
1508a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
1518a978a17SVictor Perevertkin "Could not retrieve config descriptor size, zero bytes transferred, "
1528a978a17SVictor Perevertkin " %!STATUS!", status);
1538a978a17SVictor Perevertkin
1548a978a17SVictor Perevertkin goto Done;
1558a978a17SVictor Perevertkin }
1568a978a17SVictor Perevertkin else if (config.wTotalLength < size) {
1578a978a17SVictor Perevertkin //
1588a978a17SVictor Perevertkin // Not enough info returned
1598a978a17SVictor Perevertkin //
1608a978a17SVictor Perevertkin status = STATUS_UNSUCCESSFUL;
1618a978a17SVictor Perevertkin
1628a978a17SVictor Perevertkin DoTraceLevelMessage(
1638a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
1648a978a17SVictor Perevertkin "Could not retrieve config descriptor size, config.wTotalLength %d < "
1658a978a17SVictor Perevertkin "sizeof(config descriptor) (%d), %!STATUS!",
1668a978a17SVictor Perevertkin config.wTotalLength, size, status);
1678a978a17SVictor Perevertkin
1688a978a17SVictor Perevertkin goto Done;
1698a978a17SVictor Perevertkin }
1708a978a17SVictor Perevertkin
1718a978a17SVictor Perevertkin //
1728a978a17SVictor Perevertkin // Allocate an additional memory at the end of the buffer so if we
1738a978a17SVictor Perevertkin // accidentily access fields beyond the end of the buffer we don't crash
1748a978a17SVictor Perevertkin
1758a978a17SVictor Perevertkin //
1768a978a17SVictor Perevertkin
1778a978a17SVictor Perevertkin
1788a978a17SVictor Perevertkin
1798a978a17SVictor Perevertkin
1808a978a17SVictor Perevertkin
1818a978a17SVictor Perevertkin size = config.wTotalLength;
1828a978a17SVictor Perevertkin ULONG paddedSize = size + sizeof(USB_DEVICE_DESCRIPTOR);
1838a978a17SVictor Perevertkin
1848a978a17SVictor Perevertkin m_ConfigDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)
1858a978a17SVictor Perevertkin FxPoolAllocate(GetDriverGlobals(),
1868a978a17SVictor Perevertkin NonPagedPool,
1878a978a17SVictor Perevertkin paddedSize);
1888a978a17SVictor Perevertkin
1898a978a17SVictor Perevertkin if (m_ConfigDescriptor == NULL) {
1908a978a17SVictor Perevertkin status = STATUS_INSUFFICIENT_RESOURCES;
1918a978a17SVictor Perevertkin
1928a978a17SVictor Perevertkin DoTraceLevelMessage(
1938a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
1948a978a17SVictor Perevertkin "Could not allocate %d bytes for config descriptor, %!STATUS!",
1958a978a17SVictor Perevertkin paddedSize, status);
1968a978a17SVictor Perevertkin
1978a978a17SVictor Perevertkin goto Done;
1988a978a17SVictor Perevertkin }
1998a978a17SVictor Perevertkin
2008a978a17SVictor Perevertkin RtlZeroMemory(m_ConfigDescriptor, paddedSize);
2018a978a17SVictor Perevertkin
2028a978a17SVictor Perevertkin UsbBuildGetDescriptorRequest(&urb,
2038a978a17SVictor Perevertkin sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST),
2048a978a17SVictor Perevertkin USB_CONFIGURATION_DESCRIPTOR_TYPE,
2058a978a17SVictor Perevertkin 0,
2068a978a17SVictor Perevertkin 0,
2078a978a17SVictor Perevertkin m_ConfigDescriptor,
2088a978a17SVictor Perevertkin NULL,
2098a978a17SVictor Perevertkin size,
2108a978a17SVictor Perevertkin NULL);
2118a978a17SVictor Perevertkin
2128a978a17SVictor Perevertkin request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_SUCCESS);
2138a978a17SVictor Perevertkin request.m_TrueRequest->ClearFieldsForReuse();
2148a978a17SVictor Perevertkin FxFormatUsbRequest(request.m_TrueRequest, &urb, FxUrbTypeLegacy, NULL);
2158a978a17SVictor Perevertkin
2168a978a17SVictor Perevertkin status = SubmitSync(request.m_TrueRequest, &options);
2178a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
2188a978a17SVictor Perevertkin DoTraceLevelMessage(
2198a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
2208a978a17SVictor Perevertkin "Could not retrieve config descriptor, %!STATUS!", status);
2218a978a17SVictor Perevertkin goto Done;
2228a978a17SVictor Perevertkin } else if(m_ConfigDescriptor->wTotalLength != size) {
2238a978a17SVictor Perevertkin //
2248a978a17SVictor Perevertkin // Invalid wTotalLength
2258a978a17SVictor Perevertkin //
2268a978a17SVictor Perevertkin status = STATUS_DEVICE_DATA_ERROR;
2278a978a17SVictor Perevertkin DoTraceLevelMessage(
2288a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
2298a978a17SVictor Perevertkin "Defective USB device reported two different config descriptor "
2308a978a17SVictor Perevertkin "wTotalLength values: %d and %d, %!STATUS!",
2318a978a17SVictor Perevertkin size, m_ConfigDescriptor->wTotalLength, status);
2328a978a17SVictor Perevertkin goto Done;
2338a978a17SVictor Perevertkin }
2348a978a17SVictor Perevertkin
2358a978a17SVictor Perevertkin //
2368a978a17SVictor Perevertkin // Check to see if we are wait wake capable
2378a978a17SVictor Perevertkin //
2388a978a17SVictor Perevertkin if (m_ConfigDescriptor->bmAttributes & USB_CONFIG_REMOTE_WAKEUP) {
2398a978a17SVictor Perevertkin m_Traits |= WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE;
2408a978a17SVictor Perevertkin }
2418a978a17SVictor Perevertkin
2428a978a17SVictor Perevertkin //
2438a978a17SVictor Perevertkin // Check to see if we are self or bus powered
2448a978a17SVictor Perevertkin //
2458a978a17SVictor Perevertkin USHORT deviceStatus;
2468a978a17SVictor Perevertkin
2478a978a17SVictor Perevertkin UsbBuildGetStatusRequest(&urb,
2488a978a17SVictor Perevertkin URB_FUNCTION_GET_STATUS_FROM_DEVICE,
2498a978a17SVictor Perevertkin 0,
2508a978a17SVictor Perevertkin &deviceStatus,
2518a978a17SVictor Perevertkin NULL,
2528a978a17SVictor Perevertkin NULL);
2538a978a17SVictor Perevertkin
2548a978a17SVictor Perevertkin request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_SUCCESS);
2558a978a17SVictor Perevertkin request.m_TrueRequest->ClearFieldsForReuse();
2568a978a17SVictor Perevertkin FxFormatUsbRequest(request.m_TrueRequest, &urb, FxUrbTypeLegacy, NULL);
2578a978a17SVictor Perevertkin
2588a978a17SVictor Perevertkin status = SubmitSync(request.m_TrueRequest, &options);
2598a978a17SVictor Perevertkin if (NT_SUCCESS(status) && (deviceStatus & USB_GETSTATUS_SELF_POWERED)) {
2608a978a17SVictor Perevertkin m_Traits |= WDF_USB_DEVICE_TRAIT_SELF_POWERED;
2618a978a17SVictor Perevertkin }
2628a978a17SVictor Perevertkin
2638a978a17SVictor Perevertkin //
2648a978a17SVictor Perevertkin // Revert back to success b/c we don't care if the usb device get status
2658a978a17SVictor Perevertkin // fails
2668a978a17SVictor Perevertkin //
2678a978a17SVictor Perevertkin status = STATUS_SUCCESS;
2688a978a17SVictor Perevertkin
2698a978a17SVictor Perevertkin USB_BUS_INTERFACE_USBDI_V1 busIf;
2708a978a17SVictor Perevertkin
2718a978a17SVictor Perevertkin RtlZeroMemory(&busIf, sizeof(busIf));
2728a978a17SVictor Perevertkin
2738a978a17SVictor Perevertkin //
2748a978a17SVictor Perevertkin // All PNP irps must have this initial status
2758a978a17SVictor Perevertkin //
2768a978a17SVictor Perevertkin request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_NOT_SUPPORTED);
2778a978a17SVictor Perevertkin request.m_TrueRequest->ClearFieldsForReuse();
2788a978a17SVictor Perevertkin
2798a978a17SVictor Perevertkin FxQueryInterface::_FormatIrp(
2808a978a17SVictor Perevertkin request.m_TrueRequest->GetSubmitFxIrp()->GetIrp(),
2818a978a17SVictor Perevertkin &USB_BUS_INTERFACE_USBDI_GUID,
2828a978a17SVictor Perevertkin (PINTERFACE) &busIf,
2838a978a17SVictor Perevertkin sizeof(busIf),
2848a978a17SVictor Perevertkin USB_BUSIF_USBDI_VERSION_1);
2858a978a17SVictor Perevertkin
2868a978a17SVictor Perevertkin request.m_TrueRequest->VerifierSetFormatted();
2878a978a17SVictor Perevertkin
2888a978a17SVictor Perevertkin status = SubmitSync(request.m_TrueRequest);
2898a978a17SVictor Perevertkin
2908a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
2918a978a17SVictor Perevertkin //
2928a978a17SVictor Perevertkin // Retry with the older interface
2938a978a17SVictor Perevertkin //
2948a978a17SVictor Perevertkin RtlZeroMemory(&busIf, sizeof(busIf));
2958a978a17SVictor Perevertkin
2968a978a17SVictor Perevertkin //
2978a978a17SVictor Perevertkin // All PNP irps must have this initial status
2988a978a17SVictor Perevertkin //
2998a978a17SVictor Perevertkin
3008a978a17SVictor Perevertkin request.m_TrueRequest->GetSubmitFxIrp()->Reuse(STATUS_NOT_SUPPORTED);
3018a978a17SVictor Perevertkin request.m_TrueRequest->ClearFieldsForReuse();
3028a978a17SVictor Perevertkin
3038a978a17SVictor Perevertkin FxQueryInterface::_FormatIrp(
3048a978a17SVictor Perevertkin request.m_TrueRequest->GetSubmitFxIrp()->GetIrp(),
3058a978a17SVictor Perevertkin &USB_BUS_INTERFACE_USBDI_GUID,
3068a978a17SVictor Perevertkin (PINTERFACE) &busIf,
3078a978a17SVictor Perevertkin sizeof(USB_BUS_INTERFACE_USBDI_V0),
3088a978a17SVictor Perevertkin USB_BUSIF_USBDI_VERSION_0);
3098a978a17SVictor Perevertkin
3108a978a17SVictor Perevertkin request.m_TrueRequest->VerifierSetFormatted();
3118a978a17SVictor Perevertkin
3128a978a17SVictor Perevertkin status = SubmitSync(request.m_TrueRequest);
3138a978a17SVictor Perevertkin }
3148a978a17SVictor Perevertkin
3158a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
3168a978a17SVictor Perevertkin //
3178a978a17SVictor Perevertkin // Need to check for NULL b/c we may have only retrieved the V0 interface
3188a978a17SVictor Perevertkin //
3198a978a17SVictor Perevertkin if (busIf.IsDeviceHighSpeed != NULL &&
3208a978a17SVictor Perevertkin busIf.IsDeviceHighSpeed(busIf.BusContext)) {
3218a978a17SVictor Perevertkin m_Traits |= WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED;
3228a978a17SVictor Perevertkin }
3238a978a17SVictor Perevertkin
3248a978a17SVictor Perevertkin //
3258a978a17SVictor Perevertkin // Stash these off for later
3268a978a17SVictor Perevertkin //
3278a978a17SVictor Perevertkin m_QueryBusTime = busIf.QueryBusTime;
3288a978a17SVictor Perevertkin m_BusInterfaceContext = busIf.BusContext;
3298a978a17SVictor Perevertkin m_BusInterfaceDereference = busIf.InterfaceDereference;
3308a978a17SVictor Perevertkin
3318a978a17SVictor Perevertkin ASSERT(busIf.GetUSBDIVersion != NULL);
3328a978a17SVictor Perevertkin busIf.GetUSBDIVersion(busIf.BusContext,
3338a978a17SVictor Perevertkin &m_UsbdVersionInformation,
3348a978a17SVictor Perevertkin &m_HcdPortCapabilities);
3358a978a17SVictor Perevertkin }
3368a978a17SVictor Perevertkin else if (status == STATUS_NOT_SUPPORTED) {
3378a978a17SVictor Perevertkin //
3388a978a17SVictor Perevertkin // We will only use m_ControlPipe on stacks which do not support
3398a978a17SVictor Perevertkin // USBD_DEFAULT_PIPE_TRANSFER. If all the QIs failed, then we know
3408a978a17SVictor Perevertkin // definitively that we are running on USBD and we need m_ControlPipe
3418a978a17SVictor Perevertkin // to be != NULL for later control transfers
3428a978a17SVictor Perevertkin //
3438a978a17SVictor Perevertkin ASSERT(m_ControlPipe != NULL);
3448a978a17SVictor Perevertkin
3458a978a17SVictor Perevertkin m_OnUSBD = TRUE;
3468a978a17SVictor Perevertkin
3478a978a17SVictor Perevertkin //
3488a978a17SVictor Perevertkin // The QI failed with not supported, do not return error
3498a978a17SVictor Perevertkin //
3508a978a17SVictor Perevertkin status = STATUS_SUCCESS;
3518a978a17SVictor Perevertkin }
3528a978a17SVictor Perevertkin else {
3538a978a17SVictor Perevertkin DoTraceLevelMessage(
3548a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
3558a978a17SVictor Perevertkin "Query Interface for bus returned error, %!STATUS!", status);
3568a978a17SVictor Perevertkin }
3578a978a17SVictor Perevertkin
3588a978a17SVictor Perevertkin Done:
3598a978a17SVictor Perevertkin
3608a978a17SVictor Perevertkin return status;
3618a978a17SVictor Perevertkin }
3628a978a17SVictor Perevertkin
3638a978a17SVictor Perevertkin _Must_inspect_result_
3648a978a17SVictor Perevertkin NTSTATUS
GetString(__in_ecount (* NumCharacters)PUSHORT String,__in PUSHORT NumCharacters,__in UCHAR StringIndex,__in_opt USHORT LangID,__in_opt WDFREQUEST Request,__in_opt PWDF_REQUEST_SEND_OPTIONS Options)3658a978a17SVictor Perevertkin FxUsbDevice::GetString(
3668a978a17SVictor Perevertkin __in_ecount(*NumCharacters) PUSHORT String,
3678a978a17SVictor Perevertkin __in PUSHORT NumCharacters,
3688a978a17SVictor Perevertkin __in UCHAR StringIndex,
3698a978a17SVictor Perevertkin __in_opt USHORT LangID,
3708a978a17SVictor Perevertkin __in_opt WDFREQUEST Request,
3718a978a17SVictor Perevertkin __in_opt PWDF_REQUEST_SEND_OPTIONS Options
3728a978a17SVictor Perevertkin )
3738a978a17SVictor Perevertkin {
3748a978a17SVictor Perevertkin PUSB_STRING_DESCRIPTOR pDescriptor;
3758a978a17SVictor Perevertkin PVOID buffer;
3768a978a17SVictor Perevertkin _URB_CONTROL_DESCRIPTOR_REQUEST urb;
3778a978a17SVictor Perevertkin WDF_REQUEST_SEND_OPTIONS options, *pOptions;
3788a978a17SVictor Perevertkin USB_COMMON_DESCRIPTOR common;
3798a978a17SVictor Perevertkin ULONG length;
3808a978a17SVictor Perevertkin NTSTATUS status;
3818a978a17SVictor Perevertkin
3828a978a17SVictor Perevertkin FxSyncRequest request(GetDriverGlobals(), NULL, Request);
3838a978a17SVictor Perevertkin
3848a978a17SVictor Perevertkin //
3858a978a17SVictor Perevertkin // FxSyncRequest always succeesds for KM.
3868a978a17SVictor Perevertkin //
3878a978a17SVictor Perevertkin status = request.Initialize();
3888a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
3898a978a17SVictor Perevertkin DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
3908a978a17SVictor Perevertkin "Failed to initialize FxSyncRequest");
3918a978a17SVictor Perevertkin return status;
3928a978a17SVictor Perevertkin }
3938a978a17SVictor Perevertkin
3948a978a17SVictor Perevertkin buffer = NULL;
3958a978a17SVictor Perevertkin
3968a978a17SVictor Perevertkin status = request.m_TrueRequest->ValidateTarget(this);
3978a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
3988a978a17SVictor Perevertkin goto Done;
3998a978a17SVictor Perevertkin }
4008a978a17SVictor Perevertkin
4018a978a17SVictor Perevertkin RtlZeroMemory(&urb, sizeof(urb));
4028a978a17SVictor Perevertkin
4038a978a17SVictor Perevertkin if (String != NULL) {
4048a978a17SVictor Perevertkin length = sizeof(USB_STRING_DESCRIPTOR) + (*NumCharacters - 1) * sizeof(WCHAR);
4058a978a17SVictor Perevertkin
4068a978a17SVictor Perevertkin buffer = FxPoolAllocate(GetDriverGlobals(),
4078a978a17SVictor Perevertkin NonPagedPool,
4088a978a17SVictor Perevertkin length);
4098a978a17SVictor Perevertkin
4108a978a17SVictor Perevertkin if (buffer == NULL) {
4118a978a17SVictor Perevertkin status = STATUS_INSUFFICIENT_RESOURCES;
4128a978a17SVictor Perevertkin goto Done;
4138a978a17SVictor Perevertkin }
4148a978a17SVictor Perevertkin
4158a978a17SVictor Perevertkin RtlZeroMemory(buffer, length);
4168a978a17SVictor Perevertkin pDescriptor = (PUSB_STRING_DESCRIPTOR) buffer;
4178a978a17SVictor Perevertkin }
4188a978a17SVictor Perevertkin else {
4198a978a17SVictor Perevertkin RtlZeroMemory(&common, sizeof(common));
4208a978a17SVictor Perevertkin
4218a978a17SVictor Perevertkin length = sizeof(USB_COMMON_DESCRIPTOR);
4228a978a17SVictor Perevertkin pDescriptor = (PUSB_STRING_DESCRIPTOR) &common;
4238a978a17SVictor Perevertkin }
4248a978a17SVictor Perevertkin
4258a978a17SVictor Perevertkin UsbBuildGetDescriptorRequest((PURB) &urb,
4268a978a17SVictor Perevertkin sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST),
4278a978a17SVictor Perevertkin USB_STRING_DESCRIPTOR_TYPE,
4288a978a17SVictor Perevertkin StringIndex,
4298a978a17SVictor Perevertkin LangID,
4308a978a17SVictor Perevertkin pDescriptor,
4318a978a17SVictor Perevertkin NULL,
4328a978a17SVictor Perevertkin length,
4338a978a17SVictor Perevertkin NULL);
4348a978a17SVictor Perevertkin
4358a978a17SVictor Perevertkin if (Options != NULL) {
4368a978a17SVictor Perevertkin pOptions = Options;
4378a978a17SVictor Perevertkin }
4388a978a17SVictor Perevertkin else {
4398a978a17SVictor Perevertkin WDF_REQUEST_SEND_OPTIONS_INIT(&options, 0);
4408a978a17SVictor Perevertkin WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&options,
4418a978a17SVictor Perevertkin WDF_REL_TIMEOUT_IN_SEC(2));
4428a978a17SVictor Perevertkin
4438a978a17SVictor Perevertkin pOptions = &options;
4448a978a17SVictor Perevertkin }
4458a978a17SVictor Perevertkin #pragma prefast(suppress: __WARNING_BUFFER_OVERFLOW, "this annotation change in usb.h is communicated to usb team")
4468a978a17SVictor Perevertkin FxFormatUsbRequest(request.m_TrueRequest, (PURB) &urb, FxUrbTypeLegacy, NULL);
4478a978a17SVictor Perevertkin status = SubmitSync(request.m_TrueRequest, pOptions);
4488a978a17SVictor Perevertkin
4498a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
4508a978a17SVictor Perevertkin USHORT numChars;
4518a978a17SVictor Perevertkin
4528a978a17SVictor Perevertkin //
4538a978a17SVictor Perevertkin // Make sure we got an even number of bytes and that we got a header
4548a978a17SVictor Perevertkin //
4558a978a17SVictor Perevertkin if ((pDescriptor->bLength & 0x1) ||
4568a978a17SVictor Perevertkin pDescriptor->bLength < sizeof(USB_COMMON_DESCRIPTOR)) {
4578a978a17SVictor Perevertkin status = STATUS_DEVICE_DATA_ERROR;
4588a978a17SVictor Perevertkin }
4598a978a17SVictor Perevertkin else {
4608a978a17SVictor Perevertkin //
4618a978a17SVictor Perevertkin // bLength is the length of the entire descriptor. Subtract off
4628a978a17SVictor Perevertkin // the descriptor header and then divide by the size of a WCHAR.
4638a978a17SVictor Perevertkin //
4648a978a17SVictor Perevertkin numChars =
4658a978a17SVictor Perevertkin (pDescriptor->bLength - sizeof(USB_COMMON_DESCRIPTOR)) / sizeof(WCHAR);
4668a978a17SVictor Perevertkin
4678a978a17SVictor Perevertkin if (String != NULL) {
4688a978a17SVictor Perevertkin if (*NumCharacters >= numChars) {
4698a978a17SVictor Perevertkin length = numChars * sizeof(WCHAR);
4708a978a17SVictor Perevertkin }
4718a978a17SVictor Perevertkin else {
4728a978a17SVictor Perevertkin length = *NumCharacters * sizeof(WCHAR);
4738a978a17SVictor Perevertkin status = STATUS_BUFFER_OVERFLOW;
4748a978a17SVictor Perevertkin }
4758a978a17SVictor Perevertkin
4768a978a17SVictor Perevertkin *NumCharacters = numChars;
4778a978a17SVictor Perevertkin RtlCopyMemory(String, pDescriptor->bString, length);
4788a978a17SVictor Perevertkin }
4798a978a17SVictor Perevertkin else {
4808a978a17SVictor Perevertkin *NumCharacters = numChars;
4818a978a17SVictor Perevertkin }
4828a978a17SVictor Perevertkin }
4838a978a17SVictor Perevertkin }
4848a978a17SVictor Perevertkin
4858a978a17SVictor Perevertkin if (buffer != NULL) {
4868a978a17SVictor Perevertkin FxPoolFree(buffer);
4878a978a17SVictor Perevertkin }
4888a978a17SVictor Perevertkin
4898a978a17SVictor Perevertkin Done:
4908a978a17SVictor Perevertkin
4918a978a17SVictor Perevertkin return status;
4928a978a17SVictor Perevertkin }
4938a978a17SVictor Perevertkin
4948a978a17SVictor Perevertkin _Must_inspect_result_
4958a978a17SVictor Perevertkin NTSTATUS
FormatStringRequest(__in FxRequestBase * Request,__in FxRequestBuffer * RequestBuffer,__in UCHAR StringIndex,__in USHORT LangID)4968a978a17SVictor Perevertkin FxUsbDevice::FormatStringRequest(
4978a978a17SVictor Perevertkin __in FxRequestBase* Request,
4988a978a17SVictor Perevertkin __in FxRequestBuffer *RequestBuffer,
4998a978a17SVictor Perevertkin __in UCHAR StringIndex,
5008a978a17SVictor Perevertkin __in USHORT LangID
5018a978a17SVictor Perevertkin )
5028a978a17SVictor Perevertkin /*++
5038a978a17SVictor Perevertkin
5048a978a17SVictor Perevertkin Routine Description:
5058a978a17SVictor Perevertkin Formats a request to retrieve a string from a string descriptor
5068a978a17SVictor Perevertkin
5078a978a17SVictor Perevertkin Arguments:
5088a978a17SVictor Perevertkin Request - request to format
5098a978a17SVictor Perevertkin
5108a978a17SVictor Perevertkin RequestBuffer - Buffer to be filled in when the request has completed
5118a978a17SVictor Perevertkin
5128a978a17SVictor Perevertkin StringIndex - index of the string
5138a978a17SVictor Perevertkin
5148a978a17SVictor Perevertkin LandID - language ID of the string to be retrieved
5158a978a17SVictor Perevertkin
5168a978a17SVictor Perevertkin Return Value:
5178a978a17SVictor Perevertkin NTSTATUS
5188a978a17SVictor Perevertkin
5198a978a17SVictor Perevertkin --*/
5208a978a17SVictor Perevertkin {
5218a978a17SVictor Perevertkin FxUsbDeviceStringContext* pContext;
5228a978a17SVictor Perevertkin NTSTATUS status;
5238a978a17SVictor Perevertkin FX_URB_TYPE urbType;
5248a978a17SVictor Perevertkin
5258a978a17SVictor Perevertkin status = Request->ValidateTarget(this);
5268a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
5278a978a17SVictor Perevertkin DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
5288a978a17SVictor Perevertkin "WDFUSBDEVICE %p, Request %p, setting target failed, "
5298a978a17SVictor Perevertkin "%!STATUS!", GetHandle(), Request, status);
5308a978a17SVictor Perevertkin
5318a978a17SVictor Perevertkin return status;
5328a978a17SVictor Perevertkin }
5338a978a17SVictor Perevertkin
5348a978a17SVictor Perevertkin if (Request->HasContextType(FX_RCT_USB_STRING_REQUEST)) {
5358a978a17SVictor Perevertkin pContext = (FxUsbDeviceStringContext*) Request->GetContext();
5368a978a17SVictor Perevertkin }
5378a978a17SVictor Perevertkin else {
5388a978a17SVictor Perevertkin
5398a978a17SVictor Perevertkin urbType = GetFxUrbTypeForRequest(Request);
5408a978a17SVictor Perevertkin pContext = new(GetDriverGlobals()) FxUsbDeviceStringContext(urbType);
5418a978a17SVictor Perevertkin if (pContext == NULL) {
5428a978a17SVictor Perevertkin return STATUS_INSUFFICIENT_RESOURCES;
5438a978a17SVictor Perevertkin }
5448a978a17SVictor Perevertkin
5458a978a17SVictor Perevertkin if (urbType == FxUrbTypeUsbdAllocated) {
5468a978a17SVictor Perevertkin status = pContext->AllocateUrb(m_USBDHandle);
5478a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
5488a978a17SVictor Perevertkin DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
5498a978a17SVictor Perevertkin "FxUsbDeviceStringContext::AllocateUrb failed, %!STATUS!", status);
5508a978a17SVictor Perevertkin delete pContext;
5518a978a17SVictor Perevertkin return status;
5528a978a17SVictor Perevertkin }
5538a978a17SVictor Perevertkin
5548a978a17SVictor Perevertkin //
5558a978a17SVictor Perevertkin // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
5568a978a17SVictor Perevertkin // important to release those resorces before the devnode is removed. Those
5578a978a17SVictor Perevertkin // resoruces are removed at the time Request is disposed.
5588a978a17SVictor Perevertkin //
5598a978a17SVictor Perevertkin Request->EnableContextDisposeNotification();
5608a978a17SVictor Perevertkin }
5618a978a17SVictor Perevertkin
5628a978a17SVictor Perevertkin Request->SetContext(pContext);
5638a978a17SVictor Perevertkin }
5648a978a17SVictor Perevertkin
5658a978a17SVictor Perevertkin status = pContext->AllocateDescriptor(GetDriverGlobals(),
5668a978a17SVictor Perevertkin RequestBuffer->GetBufferLength());
5678a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
5688a978a17SVictor Perevertkin return status;
5698a978a17SVictor Perevertkin }
5708a978a17SVictor Perevertkin
5718a978a17SVictor Perevertkin pContext->StoreAndReferenceMemory(RequestBuffer);
5728a978a17SVictor Perevertkin pContext->SetUrbInfo(StringIndex, LangID);
5738a978a17SVictor Perevertkin
5748a978a17SVictor Perevertkin if (pContext->m_Urb == &pContext->m_UrbLegacy) {
5758a978a17SVictor Perevertkin urbType = FxUrbTypeLegacy;
5768a978a17SVictor Perevertkin }
5778a978a17SVictor Perevertkin else {
5788a978a17SVictor Perevertkin urbType = FxUrbTypeUsbdAllocated;
5798a978a17SVictor Perevertkin }
5808a978a17SVictor Perevertkin
5818a978a17SVictor Perevertkin FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
5828a978a17SVictor Perevertkin
5838a978a17SVictor Perevertkin return STATUS_SUCCESS;
5848a978a17SVictor Perevertkin }
5858a978a17SVictor Perevertkin
5868a978a17SVictor Perevertkin _Must_inspect_result_
5878a978a17SVictor Perevertkin NTSTATUS
FormatControlRequest(__in FxRequestBase * Request,__in PWDF_USB_CONTROL_SETUP_PACKET SetupPacket,__in FxRequestBuffer * RequestBuffer)5888a978a17SVictor Perevertkin FxUsbDevice::FormatControlRequest(
5898a978a17SVictor Perevertkin __in FxRequestBase* Request,
5908a978a17SVictor Perevertkin __in PWDF_USB_CONTROL_SETUP_PACKET SetupPacket,
5918a978a17SVictor Perevertkin __in FxRequestBuffer *RequestBuffer
5928a978a17SVictor Perevertkin )
5938a978a17SVictor Perevertkin {
5948a978a17SVictor Perevertkin FxUsbDeviceControlContext* pContext;
5958a978a17SVictor Perevertkin NTSTATUS status;
5968a978a17SVictor Perevertkin size_t bufferSize;
5978a978a17SVictor Perevertkin FX_URB_TYPE urbType;
5988a978a17SVictor Perevertkin
5998a978a17SVictor Perevertkin bufferSize = RequestBuffer->GetBufferLength();
6008a978a17SVictor Perevertkin
6018a978a17SVictor Perevertkin //
6028a978a17SVictor Perevertkin // We can only transfer 2 bytes worth of data, so if the buffer is larger,
6038a978a17SVictor Perevertkin // fail here.
6048a978a17SVictor Perevertkin //
6058a978a17SVictor Perevertkin if (bufferSize > 0xFFFF) {
6068a978a17SVictor Perevertkin DoTraceLevelMessage(
6078a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
6088a978a17SVictor Perevertkin "Control transfer buffer is limited to 0xFFFF bytes in size, "
6098a978a17SVictor Perevertkin "%I64d requested ", bufferSize);
6108a978a17SVictor Perevertkin
6118a978a17SVictor Perevertkin return STATUS_INVALID_PARAMETER;
6128a978a17SVictor Perevertkin }
6138a978a17SVictor Perevertkin
6148a978a17SVictor Perevertkin status = Request->ValidateTarget(this);
6158a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
6168a978a17SVictor Perevertkin DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
6178a978a17SVictor Perevertkin "WDFUSBDEVICE %p, Request %p, setting target failed, "
6188a978a17SVictor Perevertkin "%!STATUS!", GetHandle(), Request, status);
6198a978a17SVictor Perevertkin
6208a978a17SVictor Perevertkin return status;
6218a978a17SVictor Perevertkin }
6228a978a17SVictor Perevertkin
6238a978a17SVictor Perevertkin if (Request->HasContextType(FX_RCT_USB_CONTROL_REQUEST)) {
6248a978a17SVictor Perevertkin pContext = (FxUsbDeviceControlContext*) Request->GetContext();
6258a978a17SVictor Perevertkin }
6268a978a17SVictor Perevertkin else {
6278a978a17SVictor Perevertkin
6288a978a17SVictor Perevertkin urbType = GetFxUrbTypeForRequest(Request);
6298a978a17SVictor Perevertkin pContext = new(GetDriverGlobals()) FxUsbDeviceControlContext(urbType);
6308a978a17SVictor Perevertkin if (pContext == NULL) {
6318a978a17SVictor Perevertkin return STATUS_INSUFFICIENT_RESOURCES;
6328a978a17SVictor Perevertkin }
6338a978a17SVictor Perevertkin
6348a978a17SVictor Perevertkin if (urbType == FxUrbTypeUsbdAllocated) {
6358a978a17SVictor Perevertkin status = pContext->AllocateUrb(m_USBDHandle);
6368a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
6378a978a17SVictor Perevertkin DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
6388a978a17SVictor Perevertkin "FxUsbDeviceControlContext::AllocateUrb Failed, %!STATUS!", status);
6398a978a17SVictor Perevertkin
6408a978a17SVictor Perevertkin delete pContext;
6418a978a17SVictor Perevertkin return status;
6428a978a17SVictor Perevertkin }
6438a978a17SVictor Perevertkin //
6448a978a17SVictor Perevertkin // Since the AllocateUrb routine calls USBD_xxxUrbAllocate APIs to allocate an Urb, it is
6458a978a17SVictor Perevertkin // important to release those resorces before the devnode is removed. Those
6468a978a17SVictor Perevertkin // resoruces are removed at the time Request is disposed.
6478a978a17SVictor Perevertkin //
6488a978a17SVictor Perevertkin Request->EnableContextDisposeNotification();
6498a978a17SVictor Perevertkin }
6508a978a17SVictor Perevertkin
6518a978a17SVictor Perevertkin Request->SetContext(pContext);
6528a978a17SVictor Perevertkin }
6538a978a17SVictor Perevertkin
6548a978a17SVictor Perevertkin if (RequestBuffer->HasMdl()) {
6558a978a17SVictor Perevertkin PMDL pMdl;
6568a978a17SVictor Perevertkin
6578a978a17SVictor Perevertkin pMdl = NULL;
6588a978a17SVictor Perevertkin ASSERT(pContext->m_PartialMdl == NULL);
6598a978a17SVictor Perevertkin
6608a978a17SVictor Perevertkin status = RequestBuffer->GetOrAllocateMdl(GetDriverGlobals(),
6618a978a17SVictor Perevertkin &pMdl,
6628a978a17SVictor Perevertkin &pContext->m_PartialMdl,
6638a978a17SVictor Perevertkin &pContext->m_UnlockPages,
6648a978a17SVictor Perevertkin IoModifyAccess);
6658a978a17SVictor Perevertkin
6668a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
6678a978a17SVictor Perevertkin return status;
6688a978a17SVictor Perevertkin }
6698a978a17SVictor Perevertkin
6708a978a17SVictor Perevertkin ASSERT(pMdl != NULL);
6718a978a17SVictor Perevertkin }
6728a978a17SVictor Perevertkin
6738a978a17SVictor Perevertkin pContext->StoreAndReferenceMemory(this, RequestBuffer, SetupPacket);
6748a978a17SVictor Perevertkin
6758a978a17SVictor Perevertkin if (pContext->m_Urb == &pContext->m_UrbLegacy) {
6768a978a17SVictor Perevertkin urbType = FxUrbTypeLegacy;
6778a978a17SVictor Perevertkin }
6788a978a17SVictor Perevertkin else {
6798a978a17SVictor Perevertkin urbType = FxUrbTypeUsbdAllocated;
6808a978a17SVictor Perevertkin }
6818a978a17SVictor Perevertkin
6828a978a17SVictor Perevertkin FxFormatUsbRequest(Request, (PURB)pContext->m_Urb, urbType, m_USBDHandle);
6838a978a17SVictor Perevertkin
6848a978a17SVictor Perevertkin return STATUS_SUCCESS;
6858a978a17SVictor Perevertkin }
6868a978a17SVictor Perevertkin
6878a978a17SVictor Perevertkin VOID
StoreAndReferenceMemory(__in FxUsbDevice * Device,__in FxRequestBuffer * Buffer,__in PWDF_USB_CONTROL_SETUP_PACKET SetupPacket)6888a978a17SVictor Perevertkin FxUsbDeviceControlContext::StoreAndReferenceMemory(
6898a978a17SVictor Perevertkin __in FxUsbDevice* Device,
6908a978a17SVictor Perevertkin __in FxRequestBuffer* Buffer,
6918a978a17SVictor Perevertkin __in PWDF_USB_CONTROL_SETUP_PACKET SetupPacket
6928a978a17SVictor Perevertkin )
6938a978a17SVictor Perevertkin {
6948a978a17SVictor Perevertkin SetUsbType(WdfUsbRequestTypeDeviceControlTransfer);
6958a978a17SVictor Perevertkin
6968a978a17SVictor Perevertkin RtlZeroMemory(m_Urb, sizeof(*m_Urb));
6978a978a17SVictor Perevertkin
6988a978a17SVictor Perevertkin m_Urb->Hdr.Function = URB_FUNCTION_CONTROL_TRANSFER;
6998a978a17SVictor Perevertkin m_Urb->Hdr.Length = sizeof(*m_Urb);
7008a978a17SVictor Perevertkin
701*1f377076SVictor Perevertkin FxUsbRequestContext::StoreAndReferenceMemory(Buffer); // __super call
7028a978a17SVictor Perevertkin
7038a978a17SVictor Perevertkin //
7048a978a17SVictor Perevertkin // Set the values using what is stored in the buffer
7058a978a17SVictor Perevertkin //
7068a978a17SVictor Perevertkin Buffer->AssignValues(&m_Urb->TransferBuffer,
7078a978a17SVictor Perevertkin &m_Urb->TransferBufferMDL,
7088a978a17SVictor Perevertkin &m_Urb->TransferBufferLength);
7098a978a17SVictor Perevertkin
7108a978a17SVictor Perevertkin RtlCopyMemory(&m_Urb->SetupPacket[0],
7118a978a17SVictor Perevertkin &SetupPacket->Generic.Bytes[0],
7128a978a17SVictor Perevertkin sizeof(m_Urb->SetupPacket));
7138a978a17SVictor Perevertkin
7148a978a17SVictor Perevertkin //
7158a978a17SVictor Perevertkin // also indicate the length of the buffer in the header
7168a978a17SVictor Perevertkin //
7178a978a17SVictor Perevertkin ((PWDF_USB_CONTROL_SETUP_PACKET) &m_Urb->SetupPacket[0])->Packet.wLength =
7188a978a17SVictor Perevertkin (USHORT) m_Urb->TransferBufferLength;
7198a978a17SVictor Perevertkin
7208a978a17SVictor Perevertkin //
7218a978a17SVictor Perevertkin // Control transfers are always short OK. USBD_TRANSFER_DIRECTION_IN may
7228a978a17SVictor Perevertkin // be OR'ed in later.
7238a978a17SVictor Perevertkin //
7248a978a17SVictor Perevertkin m_Urb->TransferFlags = USBD_SHORT_TRANSFER_OK;
7258a978a17SVictor Perevertkin
7268a978a17SVictor Perevertkin //
7278a978a17SVictor Perevertkin // Get the direction out of the setup packet
7288a978a17SVictor Perevertkin //
7298a978a17SVictor Perevertkin if (SetupPacket->Packet.bm.Request.Dir == BMREQUEST_DEVICE_TO_HOST) {
7308a978a17SVictor Perevertkin m_Urb->TransferFlags |= USBD_TRANSFER_DIRECTION_IN;
7318a978a17SVictor Perevertkin }
7328a978a17SVictor Perevertkin
7338a978a17SVictor Perevertkin if (Device->OnUSBD()) {
7348a978a17SVictor Perevertkin m_Urb->PipeHandle = Device->GetControlPipeHandle();
7358a978a17SVictor Perevertkin }
7368a978a17SVictor Perevertkin else {
7378a978a17SVictor Perevertkin //
7388a978a17SVictor Perevertkin // USBPORT supports this flag
7398a978a17SVictor Perevertkin //
7408a978a17SVictor Perevertkin m_Urb->TransferFlags |= USBD_DEFAULT_PIPE_TRANSFER;
7418a978a17SVictor Perevertkin }
7428a978a17SVictor Perevertkin
7438a978a17SVictor Perevertkin //
7448a978a17SVictor Perevertkin // If we have built a partial MDL, use that instead. TransferBufferLength
7458a978a17SVictor Perevertkin // is still valid because the Offsets or length in Buffer will have been
7468a978a17SVictor Perevertkin // used to create this PartialMdl by the caller.
7478a978a17SVictor Perevertkin //
7488a978a17SVictor Perevertkin if (m_PartialMdl != NULL) {
7498a978a17SVictor Perevertkin m_Urb->TransferBufferMDL = m_PartialMdl;
7508a978a17SVictor Perevertkin }
7518a978a17SVictor Perevertkin }
7528a978a17SVictor Perevertkin
7538a978a17SVictor Perevertkin _Must_inspect_result_
7548a978a17SVictor Perevertkin NTSTATUS
7558a978a17SVictor Perevertkin FxUsbDevice::QueryUsbCapability(
7568a978a17SVictor Perevertkin __in
7578a978a17SVictor Perevertkin CONST GUID* CapabilityType,
7588a978a17SVictor Perevertkin __in
7598a978a17SVictor Perevertkin ULONG CapabilityBufferLength,
7608a978a17SVictor Perevertkin __drv_when(CapabilityBufferLength == 0, __out_opt)
7618a978a17SVictor Perevertkin __drv_when(CapabilityBufferLength != 0 && ResultLength == NULL, __out_bcount(CapabilityBufferLength))
7628a978a17SVictor Perevertkin __drv_when(CapabilityBufferLength != 0 && ResultLength != NULL, __out_bcount_part_opt(CapabilityBufferLength, *ResultLength))
7638a978a17SVictor Perevertkin PVOID CapabilityBuffer,
7648a978a17SVictor Perevertkin __out_opt
7658a978a17SVictor Perevertkin __drv_when(ResultLength != NULL,__deref_out_range(<=,CapabilityBufferLength))
7668a978a17SVictor Perevertkin PULONG ResultLength
7678a978a17SVictor Perevertkin )
7688a978a17SVictor Perevertkin {
7698a978a17SVictor Perevertkin NTSTATUS status;
7708a978a17SVictor Perevertkin
7718a978a17SVictor Perevertkin if (ResultLength != NULL) {
7728a978a17SVictor Perevertkin *ResultLength = 0;
7738a978a17SVictor Perevertkin }
7748a978a17SVictor Perevertkin
7758a978a17SVictor Perevertkin if (GetUSBDHandle() == NULL) {
7768a978a17SVictor Perevertkin status = STATUS_INVALID_DEVICE_STATE;
7778a978a17SVictor Perevertkin
7788a978a17SVictor Perevertkin DoTraceLevelMessage(
7798a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
7808a978a17SVictor Perevertkin "WDFUSBDEVICE must have been created using WdfUsbTargetDeviceCreateWithParameters, %!STATUS!",
7818a978a17SVictor Perevertkin status);
7828a978a17SVictor Perevertkin
7838a978a17SVictor Perevertkin return status;
7848a978a17SVictor Perevertkin }
7858a978a17SVictor Perevertkin
7868a978a17SVictor Perevertkin status = USBD_QueryUsbCapability(m_USBDHandle,
7878a978a17SVictor Perevertkin CapabilityType,
7888a978a17SVictor Perevertkin CapabilityBufferLength,
7898a978a17SVictor Perevertkin (PUCHAR) CapabilityBuffer,
7908a978a17SVictor Perevertkin ResultLength);
7918a978a17SVictor Perevertkin
7928a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
7938a978a17SVictor Perevertkin DoTraceLevelMessage(
7948a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
7958a978a17SVictor Perevertkin "Could not retrieve capability %!GUID!, %!STATUS!",
7968a978a17SVictor Perevertkin CapabilityType, status);
7978a978a17SVictor Perevertkin goto exit;
7988a978a17SVictor Perevertkin }
7998a978a17SVictor Perevertkin
8008a978a17SVictor Perevertkin exit:
8018a978a17SVictor Perevertkin return status;
8028a978a17SVictor Perevertkin }
8038a978a17SVictor Perevertkin
8048a978a17SVictor Perevertkin _Must_inspect_result_
8058a978a17SVictor Perevertkin NTSTATUS
SelectConfigSingle(__in PWDF_OBJECT_ATTRIBUTES PipeAttributes,__in PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS Params)8068a978a17SVictor Perevertkin FxUsbDevice::SelectConfigSingle(
8078a978a17SVictor Perevertkin __in PWDF_OBJECT_ATTRIBUTES PipeAttributes,
8088a978a17SVictor Perevertkin __in PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS Params
8098a978a17SVictor Perevertkin )
8108a978a17SVictor Perevertkin /*++
8118a978a17SVictor Perevertkin
8128a978a17SVictor Perevertkin Routine Description:
8138a978a17SVictor Perevertkin This will configure the single inteface case and pick up the first available
8148a978a17SVictor Perevertkin setting. If there are multiple settings on a single interface device
8158a978a17SVictor Perevertkin and the driver wants to pick one then the driver should use the multinterface
8168a978a17SVictor Perevertkin option to initialize.
8178a978a17SVictor Perevertkin
8188a978a17SVictor Perevertkin This takes care of the simplest case only. Configuring a multi interface
8198a978a17SVictor Perevertkin device as a single interface device would be treated as an error. There is
8208a978a17SVictor Perevertkin duplication of code with the multi case but it is better to keep these two
8218a978a17SVictor Perevertkin separate especially if more gets added.
8228a978a17SVictor Perevertkin
8238a978a17SVictor Perevertkin Arguments:
8248a978a17SVictor Perevertkin
8258a978a17SVictor Perevertkin
8268a978a17SVictor Perevertkin Return Value:
8278a978a17SVictor Perevertkin NTSTATUS
8288a978a17SVictor Perevertkin
8298a978a17SVictor Perevertkin --*/
8308a978a17SVictor Perevertkin {
8318a978a17SVictor Perevertkin //
8328a978a17SVictor Perevertkin // The array needs an extra element which is zero'd out to mark the end
8338a978a17SVictor Perevertkin //
8348a978a17SVictor Perevertkin USBD_INTERFACE_LIST_ENTRY listEntry[2];
8358a978a17SVictor Perevertkin PURB urb;
8368a978a17SVictor Perevertkin NTSTATUS status;
8378a978a17SVictor Perevertkin
8388a978a17SVictor Perevertkin RtlZeroMemory(&Params->Types.SingleInterface,
8398a978a17SVictor Perevertkin sizeof(Params->Types.SingleInterface));
8408a978a17SVictor Perevertkin
8418a978a17SVictor Perevertkin if (m_NumInterfaces > 1) {
8428a978a17SVictor Perevertkin status = STATUS_INVALID_PARAMETER;
8438a978a17SVictor Perevertkin
8448a978a17SVictor Perevertkin DoTraceLevelMessage(
8458a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
8468a978a17SVictor Perevertkin "WDFUSBDEVICE %p cannot be auto configured for a single interface "
8478a978a17SVictor Perevertkin "since there are %d interfaces on the device, %!STATUS!",
8488a978a17SVictor Perevertkin GetHandle(), m_NumInterfaces, status);
8498a978a17SVictor Perevertkin
8508a978a17SVictor Perevertkin return status;
8518a978a17SVictor Perevertkin }
8528a978a17SVictor Perevertkin
8538a978a17SVictor Perevertkin RtlZeroMemory(&listEntry[0], sizeof(listEntry));
8548a978a17SVictor Perevertkin
8558a978a17SVictor Perevertkin //
8568a978a17SVictor Perevertkin // Use AlternateSetting 0 by default
8578a978a17SVictor Perevertkin //
8588a978a17SVictor Perevertkin listEntry[0].InterfaceDescriptor = m_Interfaces[0]->GetSettingDescriptor(0);
8598a978a17SVictor Perevertkin
8608a978a17SVictor Perevertkin if (listEntry[0].InterfaceDescriptor == NULL) {
8618a978a17SVictor Perevertkin DoTraceLevelMessage(
8628a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
8638a978a17SVictor Perevertkin "WDFUSBDEVICE %p could not retrieve AlternateSetting 0 for "
8648a978a17SVictor Perevertkin "bInterfaceNumber %d", GetHandle(),
8658a978a17SVictor Perevertkin m_Interfaces[0]->m_InterfaceNumber);
8668a978a17SVictor Perevertkin
8678a978a17SVictor Perevertkin return STATUS_INVALID_PARAMETER;
8688a978a17SVictor Perevertkin }
8698a978a17SVictor Perevertkin
8708a978a17SVictor Perevertkin urb = FxUsbCreateConfigRequest(GetDriverGlobals(),
8718a978a17SVictor Perevertkin m_ConfigDescriptor,
8728a978a17SVictor Perevertkin &listEntry[0],
8738a978a17SVictor Perevertkin GetDefaultMaxTransferSize());
8748a978a17SVictor Perevertkin
8758a978a17SVictor Perevertkin if (urb == NULL) {
8768a978a17SVictor Perevertkin status = STATUS_INSUFFICIENT_RESOURCES;
8778a978a17SVictor Perevertkin }
8788a978a17SVictor Perevertkin else {
8798a978a17SVictor Perevertkin status = SelectConfig(PipeAttributes, urb, FxUrbTypeLegacy, NULL);
8808a978a17SVictor Perevertkin
8818a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
8828a978a17SVictor Perevertkin Params->Types.SingleInterface.NumberConfiguredPipes =
8838a978a17SVictor Perevertkin m_Interfaces[0]->GetNumConfiguredPipes();
8848a978a17SVictor Perevertkin
8858a978a17SVictor Perevertkin Params->Types.SingleInterface.ConfiguredUsbInterface =
8868a978a17SVictor Perevertkin m_Interfaces[0]->GetHandle();
8878a978a17SVictor Perevertkin }
8888a978a17SVictor Perevertkin
8898a978a17SVictor Perevertkin FxPoolFree(urb);
8908a978a17SVictor Perevertkin urb = NULL;
8918a978a17SVictor Perevertkin }
8928a978a17SVictor Perevertkin
8938a978a17SVictor Perevertkin return status;
8948a978a17SVictor Perevertkin }
8958a978a17SVictor Perevertkin
8968a978a17SVictor Perevertkin _Must_inspect_result_
8978a978a17SVictor Perevertkin NTSTATUS
SelectConfigMulti(__in PWDF_OBJECT_ATTRIBUTES PipesAttributes,__in PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS Params)8988a978a17SVictor Perevertkin FxUsbDevice::SelectConfigMulti(
8998a978a17SVictor Perevertkin __in PWDF_OBJECT_ATTRIBUTES PipesAttributes,
9008a978a17SVictor Perevertkin __in PWDF_USB_DEVICE_SELECT_CONFIG_PARAMS Params
9018a978a17SVictor Perevertkin )
9028a978a17SVictor Perevertkin /*++
9038a978a17SVictor Perevertkin
9048a978a17SVictor Perevertkin Routine Description:
9058a978a17SVictor Perevertkin Selects the configuration as described by the parameter Params. If there is a
9068a978a17SVictor Perevertkin previous active configuration, the WDFUSBPIPEs for it are stopped and
9078a978a17SVictor Perevertkin destroyed before the new configuration is selected
9088a978a17SVictor Perevertkin
9098a978a17SVictor Perevertkin Arguments:
9108a978a17SVictor Perevertkin PipesAttributes - object attributes to apply to each created WDFUSBPIPE
9118a978a17SVictor Perevertkin
9128a978a17SVictor Perevertkin Params -
9138a978a17SVictor Perevertkin
9148a978a17SVictor Perevertkin Return Value:
9158a978a17SVictor Perevertkin NTSTATUS
9168a978a17SVictor Perevertkin
9178a978a17SVictor Perevertkin --*/
9188a978a17SVictor Perevertkin {
9198a978a17SVictor Perevertkin PUSBD_INTERFACE_LIST_ENTRY pList;
9208a978a17SVictor Perevertkin PURB urb;
9218a978a17SVictor Perevertkin NTSTATUS status;
9228a978a17SVictor Perevertkin ULONG size;
9238a978a17SVictor Perevertkin UCHAR i;
9248a978a17SVictor Perevertkin PFX_DRIVER_GLOBALS pFxDriverGlobals;
9258a978a17SVictor Perevertkin
9268a978a17SVictor Perevertkin pFxDriverGlobals = GetDriverGlobals();
9278a978a17SVictor Perevertkin
9288a978a17SVictor Perevertkin Params->Types.MultiInterface.NumberOfConfiguredInterfaces = 0;
9298a978a17SVictor Perevertkin
9308a978a17SVictor Perevertkin //
9318a978a17SVictor Perevertkin // The array needs an extra element which is zero'd out to mark the end
9328a978a17SVictor Perevertkin //
9338a978a17SVictor Perevertkin size = sizeof(USBD_INTERFACE_LIST_ENTRY) * (m_NumInterfaces + 1);
9348a978a17SVictor Perevertkin pList = (PUSBD_INTERFACE_LIST_ENTRY) FxPoolAllocate(
9358a978a17SVictor Perevertkin pFxDriverGlobals,
9368a978a17SVictor Perevertkin NonPagedPool,
9378a978a17SVictor Perevertkin size
9388a978a17SVictor Perevertkin );
9398a978a17SVictor Perevertkin
9408a978a17SVictor Perevertkin if (pList == NULL) {
9418a978a17SVictor Perevertkin return STATUS_INSUFFICIENT_RESOURCES;
9428a978a17SVictor Perevertkin }
9438a978a17SVictor Perevertkin
9448a978a17SVictor Perevertkin RtlZeroMemory(pList, size);
9458a978a17SVictor Perevertkin
9468a978a17SVictor Perevertkin if (Params->Type == WdfUsbTargetDeviceSelectConfigTypeMultiInterface) {
9478a978a17SVictor Perevertkin for (i = 0; i < m_NumInterfaces; i++) {
9488a978a17SVictor Perevertkin pList[i].InterfaceDescriptor =
9498a978a17SVictor Perevertkin m_Interfaces[i]->GetSettingDescriptor(0);
9508a978a17SVictor Perevertkin
9518a978a17SVictor Perevertkin if (pList[i].InterfaceDescriptor == NULL) {
9528a978a17SVictor Perevertkin DoTraceLevelMessage(
9538a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
9548a978a17SVictor Perevertkin "WDFUSBDEVICE %p could not retrieve AlternateSetting 0 for "
9558a978a17SVictor Perevertkin "bInterfaceNumber %d", GetHandle(),
9568a978a17SVictor Perevertkin m_Interfaces[i]->m_InterfaceNumber);
9578a978a17SVictor Perevertkin
9588a978a17SVictor Perevertkin status = STATUS_INVALID_PARAMETER;
9598a978a17SVictor Perevertkin goto Done;
9608a978a17SVictor Perevertkin }
9618a978a17SVictor Perevertkin }
9628a978a17SVictor Perevertkin }
9638a978a17SVictor Perevertkin else {
9648a978a17SVictor Perevertkin //
9658a978a17SVictor Perevertkin // Type is WdfUsbTargetDeviceSelectConfigTypeInterfacesPairs
9668a978a17SVictor Perevertkin //
9678a978a17SVictor Perevertkin UCHAR interfacePairsNum = 0;
9688a978a17SVictor Perevertkin UCHAR bitArray[UCHAR_MAX/sizeof(UCHAR)];
9698a978a17SVictor Perevertkin
9708a978a17SVictor Perevertkin //
9718a978a17SVictor Perevertkin // initialize the bit array
9728a978a17SVictor Perevertkin //
9738a978a17SVictor Perevertkin RtlZeroMemory(bitArray, sizeof(bitArray));
9748a978a17SVictor Perevertkin //
9758a978a17SVictor Perevertkin // Build a list of descriptors from the Setting pairs
9768a978a17SVictor Perevertkin // passed in by the user. There could be interfaces not
9778a978a17SVictor Perevertkin // covered in the setting/interface pairs array passed.
9788a978a17SVictor Perevertkin // If that is the case return STATUS_INVALID_PARAMETER
9798a978a17SVictor Perevertkin //
9808a978a17SVictor Perevertkin for (i = 0; i < Params->Types.MultiInterface.NumberInterfaces ; i++) {
9818a978a17SVictor Perevertkin PWDF_USB_INTERFACE_SETTING_PAIR settingPair;
9828a978a17SVictor Perevertkin UCHAR interfaceNumber;
9838a978a17SVictor Perevertkin UCHAR altSettingIndex;
9848a978a17SVictor Perevertkin
9858a978a17SVictor Perevertkin settingPair = &Params->Types.MultiInterface.Pairs[i];
9868a978a17SVictor Perevertkin
9878a978a17SVictor Perevertkin status = GetInterfaceNumberFromInterface(
9888a978a17SVictor Perevertkin settingPair->UsbInterface,
9898a978a17SVictor Perevertkin &interfaceNumber
9908a978a17SVictor Perevertkin );
9918a978a17SVictor Perevertkin
9928a978a17SVictor Perevertkin //
9938a978a17SVictor Perevertkin //convert the interface handle to interface number
9948a978a17SVictor Perevertkin //
9958a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
9968a978a17SVictor Perevertkin altSettingIndex = settingPair->SettingIndex;
9978a978a17SVictor Perevertkin
9988a978a17SVictor Perevertkin //
9998a978a17SVictor Perevertkin // do the following only if the bit is not already set
10008a978a17SVictor Perevertkin //
10018a978a17SVictor Perevertkin if (FxBitArraySet(&bitArray[0], interfaceNumber) == FALSE) {
10028a978a17SVictor Perevertkin pList[interfacePairsNum].InterfaceDescriptor =
10038a978a17SVictor Perevertkin FxUsbParseConfigurationDescriptor(
10048a978a17SVictor Perevertkin m_ConfigDescriptor,
10058a978a17SVictor Perevertkin interfaceNumber,
10068a978a17SVictor Perevertkin altSettingIndex
10078a978a17SVictor Perevertkin );
10088a978a17SVictor Perevertkin
10098a978a17SVictor Perevertkin if (pList[interfacePairsNum].InterfaceDescriptor == NULL) {
10108a978a17SVictor Perevertkin status = STATUS_INVALID_PARAMETER;
10118a978a17SVictor Perevertkin DoTraceLevelMessage(
10128a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR,
10138a978a17SVictor Perevertkin TRACINGIOTARGET,
10148a978a17SVictor Perevertkin "WDFUSBDEVICE %p could not retrieve "
10158a978a17SVictor Perevertkin "AlternateSetting %d for "
10168a978a17SVictor Perevertkin "bInterfaceNumber %d, returning %!STATUS!",
10178a978a17SVictor Perevertkin GetHandle(),
10188a978a17SVictor Perevertkin altSettingIndex, interfaceNumber, status);
10198a978a17SVictor Perevertkin goto Done;
10208a978a17SVictor Perevertkin }
10218a978a17SVictor Perevertkin
10228a978a17SVictor Perevertkin interfacePairsNum++;
10238a978a17SVictor Perevertkin }
10248a978a17SVictor Perevertkin }
10258a978a17SVictor Perevertkin else {
10268a978a17SVictor Perevertkin goto Done;
10278a978a17SVictor Perevertkin }
10288a978a17SVictor Perevertkin }
10298a978a17SVictor Perevertkin
10308a978a17SVictor Perevertkin //
10318a978a17SVictor Perevertkin // Check if there are any interfaces not specified by the array. If
10328a978a17SVictor Perevertkin // there are, then select setting 0 for them.
10338a978a17SVictor Perevertkin //
10348a978a17SVictor Perevertkin if (m_NumInterfaces > interfacePairsNum) {
10358a978a17SVictor Perevertkin status = STATUS_INVALID_PARAMETER;
10368a978a17SVictor Perevertkin DoTraceLevelMessage(
10378a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
10388a978a17SVictor Perevertkin "WDFUSBDEVICE %p interface pairs set (%d) is not equal to actual "
10398a978a17SVictor Perevertkin "# of interfaces (%d) reported by the device, %!STATUS!",
10408a978a17SVictor Perevertkin GetObjectHandle(), interfacePairsNum, m_NumInterfaces, status);
10418a978a17SVictor Perevertkin goto Done;
10428a978a17SVictor Perevertkin }
10438a978a17SVictor Perevertkin } //WdfUsbTargetDeviceSelectConfigTypeInterfacesPairs
10448a978a17SVictor Perevertkin
10458a978a17SVictor Perevertkin urb = FxUsbCreateConfigRequest(
10468a978a17SVictor Perevertkin GetDriverGlobals(),
10478a978a17SVictor Perevertkin m_ConfigDescriptor,
10488a978a17SVictor Perevertkin pList,
10498a978a17SVictor Perevertkin GetDefaultMaxTransferSize()
10508a978a17SVictor Perevertkin );
10518a978a17SVictor Perevertkin
10528a978a17SVictor Perevertkin if (urb == NULL) {
10538a978a17SVictor Perevertkin status = STATUS_INSUFFICIENT_RESOURCES;
10548a978a17SVictor Perevertkin }
10558a978a17SVictor Perevertkin else {
10568a978a17SVictor Perevertkin status = SelectConfig(
10578a978a17SVictor Perevertkin PipesAttributes,
10588a978a17SVictor Perevertkin urb,
10598a978a17SVictor Perevertkin FxUrbTypeLegacy,
10608a978a17SVictor Perevertkin &Params->Types.MultiInterface.NumberOfConfiguredInterfaces);
10618a978a17SVictor Perevertkin
10628a978a17SVictor Perevertkin FxPoolFree(urb);
10638a978a17SVictor Perevertkin urb = NULL;
10648a978a17SVictor Perevertkin }
10658a978a17SVictor Perevertkin
10668a978a17SVictor Perevertkin Done:
10678a978a17SVictor Perevertkin FxPoolFree(pList);
10688a978a17SVictor Perevertkin pList = NULL;
10698a978a17SVictor Perevertkin
10708a978a17SVictor Perevertkin return status;
10718a978a17SVictor Perevertkin }
10728a978a17SVictor Perevertkin
10738a978a17SVictor Perevertkin _Must_inspect_result_
10748a978a17SVictor Perevertkin NTSTATUS
Reset(VOID)10758a978a17SVictor Perevertkin FxUsbDevice::Reset(
10768a978a17SVictor Perevertkin VOID
10778a978a17SVictor Perevertkin )
10788a978a17SVictor Perevertkin {
10798a978a17SVictor Perevertkin FxIoContext context;
10808a978a17SVictor Perevertkin FxSyncRequest request(GetDriverGlobals(), &context);
10818a978a17SVictor Perevertkin FxRequestBuffer emptyBuffer;
10828a978a17SVictor Perevertkin NTSTATUS status;
10838a978a17SVictor Perevertkin
10848a978a17SVictor Perevertkin //
10858a978a17SVictor Perevertkin // FxSyncRequest always succeesds for KM.
10868a978a17SVictor Perevertkin //
10878a978a17SVictor Perevertkin status = request.Initialize();
10888a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
10898a978a17SVictor Perevertkin DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGIOTARGET,
10908a978a17SVictor Perevertkin "Failed to initialize FxSyncRequest");
10918a978a17SVictor Perevertkin return status;
10928a978a17SVictor Perevertkin }
10938a978a17SVictor Perevertkin
10948a978a17SVictor Perevertkin status = FormatIoctlRequest(request.m_TrueRequest,
10958a978a17SVictor Perevertkin IOCTL_INTERNAL_USB_RESET_PORT,
10968a978a17SVictor Perevertkin TRUE,
10978a978a17SVictor Perevertkin &emptyBuffer,
10988a978a17SVictor Perevertkin &emptyBuffer);
10998a978a17SVictor Perevertkin if (NT_SUCCESS(status)) {
11008a978a17SVictor Perevertkin CancelSentIo();
11018a978a17SVictor Perevertkin status = SubmitSyncRequestIgnoreTargetState(request.m_TrueRequest, NULL);
11028a978a17SVictor Perevertkin }
11038a978a17SVictor Perevertkin
11048a978a17SVictor Perevertkin return status;
11058a978a17SVictor Perevertkin }
11068a978a17SVictor Perevertkin
11078a978a17SVictor Perevertkin
1108