NTSTATUS Acpi_EnumChildren ( _In_ PACPI_CONTEXT AcpiCtx, _Out_ WDFMEMORY* EnumChildrenOutput ) { NTSTATUS status; WDFDEVICE device; WDFMEMORY inputMem; PACPI_ENUM_CHILDREN_INPUT_BUFFER inputBuf; size_t inputBufSize; WDF_MEMORY_DESCRIPTOR inputMemDesc; WDFMEMORY outputMem; PACPI_ENUM_CHILDREN_OUTPUT_BUFFER outputBuf; size_t outputBufSize; WDF_MEMORY_DESCRIPTOR outputMemDesc; WDF_OBJECT_ATTRIBUTES attributes; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); device = Context_GetWdfDevice(AcpiCtx); inputMem = WDF_NO_HANDLE; outputMem = WDF_NO_HANDLE; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; inputBufSize = sizeof(*inputBuf); status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, inputBufSize, &inputMem, (PVOID*) &inputBuf); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate for %Iu bytes failed", device, inputBufSize); goto Exit; } RtlZeroMemory(inputBuf, inputBufSize); inputBuf->Signature = ACPI_ENUM_CHILDREN_INPUT_BUFFER_SIGNATURE; inputBuf->Flags = ENUM_CHILDREN_IMMEDIATE_ONLY; WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&inputMemDesc, inputMem, nullptr); outputBufSize = sizeof(*outputBuf); do { WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, outputBufSize, &outputMem, (PVOID*) &outputBuf); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate for %Iu bytes failed", device, outputBufSize); goto Exit; } WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&outputMemDesc, outputMem, nullptr); status = WdfIoTargetSendIoctlSynchronously(WdfDeviceGetIoTarget(device), NULL, IOCTL_ACPI_ENUM_CHILDREN, &inputMemDesc, &outputMemDesc, nullptr, nullptr); if (NT_SUCCESS(status)) { if (outputBuf->Signature != ACPI_ENUM_CHILDREN_OUTPUT_BUFFER_SIGNATURE) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] Invalid data in ACPI_ENUM_CHILDREN_OUTPUT_BUFFER", device); goto Exit; } // // There must be atleast one, because this device is included in the list. // if (outputBuf->NumberOfChildren < 1) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] No child devices in ACPI_ENUM_CHILDREN_OUTPUT_BUFFER", device); goto Exit; } break; } if (status != STATUS_BUFFER_OVERFLOW) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] IOCTL_ACPI_ENUM_CHILDREN failed - %!STATUS!", device, status); goto Exit; } if (outputBuf->Signature != ACPI_ENUM_CHILDREN_OUTPUT_BUFFER_SIGNATURE) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] Invalid data in ACPI_ENUM_CHILDREN_OUTPUT_BUFFER", device); goto Exit; } outputBufSize = outputBuf->NumberOfChildren; WdfObjectDelete(outputMem); outputMem = WDF_NO_HANDLE; #pragma warning(suppress:4127) } while (true); *EnumChildrenOutput = outputMem; Exit: if (inputMem != WDF_NO_HANDLE) { WdfObjectDelete(inputMem); } if (!NT_SUCCESS(status) && (outputMem != WDF_NO_HANDLE)) { WdfObjectDelete(outputMem); } TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); return status; }
VOID SDVTest_wdf_MemoryAfterReqCompletionIntIoctlAdd( _In_ WDFMEMORY Memory ) { WDF_MEMORY_DESCRIPTOR memoryDescriptor; WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memoryDescriptor, Memory, NULL); return; }
/////////////////////////////////////////////////////////////////////////////// // // BasicUsbEvtDeviceControl // // This routine is called by the framework when there is a // device control request for us to process // // INPUTS: // // Queue - Our default queue // // Request - A device control request // // OutputBufferLength - The length of the output buffer // // InputBufferLength - The length of the input buffer // // IoControlCode - The operation being performed // // OUTPUTS: // // None. // // RETURNS: // // None. // // IRQL: // // This routine is called at IRQL == PASSIVE_LEVEL, due to // our PASSIVE_LEVEL execution level contraint // // NOTES: // // /////////////////////////////////////////////////////////////////////////////// VOID BasicUsbEvtDeviceControl(WDFQUEUE Queue, WDFREQUEST Request, size_t OutputBufferLength, size_t InputBufferLength, ULONG IoControlCode) { NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDFMEMORY inputMemory; WDF_MEMORY_DESCRIPTOR inputMemoryDescriptor; PBASICUSB_DEVICE_CONTEXT devContext; #if DBG DbgPrint("BasicUsbEvtDeviceControl\n"); #endif devContext = BasicUsbGetContextFromDevice( WdfIoQueueGetDevice(Queue) ); switch (IoControlCode) { case IOCTL_OSR_BASICUSB_SET_BAR_GRAPH: { // // Validate the buffers for this request: // // OutputBufferLength - Must be zero // if (OutputBufferLength != 0) { #if DBG DbgPrint("Invalid parameter - output buffer supplied in "\ "SET_BAR_GRAPH IOCTL (%u bytes)\n", (ULONG)OutputBufferLength); #endif WdfRequestComplete(Request, STATUS_INVALID_PARAMETER); return; } // // InputBufferLength - Must be at least 1 byte // if (InputBufferLength == 0) { #if DBG DbgPrint("No input buffer supplied in SET_BAR_GRAPH IOCTL\n"); #endif WdfRequestCompleteWithInformation(Request, STATUS_BUFFER_TOO_SMALL, sizeof(UCHAR)); return; } // // We need the input memory from the request so that we can pass // it to the bus driver. // status = WdfRequestRetrieveInputMemory(Request, &inputMemory); if (!NT_SUCCESS(status)) { #if DBG DbgPrint("WdfRequestRetrieveInputMemory failed 0x%0x\n", status); #endif WdfRequestComplete(Request, status); return; } // // The routine we want to call takes a memory descriptor, so // initialize that now with the handle to the user memory. // WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&inputMemoryDescriptor, inputMemory, NULL); // // Initialize the vendor command (defined by the device) that // allows us to light the bar graph. // WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR( &controlSetupPacket, BmRequestHostToDevice, BmRequestToDevice, USBFX2LK_SET_BARGRAPH_DISPLAY, 0, 0); // // And send the vendor command as a control transfer. This // shouldn't take very long, so we'll just send it synchronously // to the device. // // // We've specified an execution level restraint of // PASSIVE_LEVEL, so we're allowed to send this request // synchronously. // ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); status = WdfUsbTargetDeviceSendControlTransferSynchronously( devContext->BasicUsbUsbDevice, WDF_NO_HANDLE, NULL, &controlSetupPacket, &inputMemoryDescriptor, NULL); if (NT_SUCCESS(status)) { // // If the request succeeded, complete the request with success // and indicate to the user how much data was transferred (in // this case a single byte was sent to the device) // WdfRequestCompleteWithInformation(Request, status, sizeof(UCHAR)); } else { // // Bad news! Just complete the request with the failure status. // #if DBG DbgPrint("WdfUsbTargetDeviceSendControlTransferSynchronously "\ "failed 0x%0x\n", status); #endif WdfRequestComplete(Request, status); } return; } case IOCTL_OSR_BASICUSB_GET_SWITCHPACK_STATE: { // // Validate the buffers for this request: // // InputBufferLength - Must be zero // if (InputBufferLength != 0) { #if DBG DbgPrint("Invalid parameter - input buffer supplied in "\ "SWITCHPACK_STATE_CHANGE_NOTIFY IOCTL (%u bytes)\n", (ULONG)InputBufferLength); #endif WdfRequestComplete(Request, STATUS_INVALID_PARAMETER); return; } // // OutputBufferLength - Must be at least 1 byte // if (OutputBufferLength == 0) { #if DBG DbgPrint("No input buffer supplied in "\ "SWITCHPACK_STATE_CHANGE_NOTIFY IOCTL\n"); #endif WdfRequestCompleteWithInformation(Request, STATUS_BUFFER_TOO_SMALL, sizeof(UCHAR)); return; } // // Forward the request to our switchpack state change requests // queue // status = WdfRequestForwardToIoQueue( Request, devContext->SwitchPackStateChangeQueue); if (!NT_SUCCESS(status)) { // // Bad news! Print out the status and fail the request. // #if DBG DbgPrint("WdfRequestForwardToIoQueue failed with Status "\ "code 0x%x", status); #endif WdfRequestComplete(Request, status); return; } return; } default: { #if DBG DbgPrint("Unknown IOCTL: 0x%x\n", IoControlCode); #endif WdfRequestCompleteWithInformation(Request, STATUS_INVALID_DEVICE_REQUEST, 0); return; } } return; }
VOID EvtIoDeviceControl( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode ) { WDFDEVICE device; PDEVICE_CONTEXT pDevContext; size_t bytesTransferred = 0; NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_MEMORY_DESCRIPTOR memDesc; WDFMEMORY memory; WDF_REQUEST_SEND_OPTIONS sendOptions; UNREFERENCED_PARAMETER(InputBufferLength); UNREFERENCED_PARAMETER(OutputBufferLength); device = WdfIoQueueGetDevice(Queue); pDevContext = GetDeviceContext(device); switch(IoControlCode) { case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY: if(InputBufferLength < sizeof(UCHAR)) { status = STATUS_BUFFER_OVERFLOW; bytesTransferred = sizeof(UCHAR); break; } status = WdfRequestRetrieveInputMemory(Request, &memory); if (!NT_SUCCESS(status)) { KdPrint(("WdfRequestRetrieveMemory failed %!STATUS!", status)); break; } WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestHostToDevice, BmRequestToDevice, USBFX2LK_SET_BARGRAPH_DISPLAY, // Request 0, // Value 0); // Index WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDesc, memory, NULL); // // Send the I/O with a timeout to avoid hanging the calling // thread indefinitely. // WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(100)); status = WdfUsbTargetDeviceSendControlTransferSynchronously( pDevContext->UsbDevice, NULL, // Optional WDFREQUEST &sendOptions, // PWDF_REQUEST_SEND_OPTIONS &controlSetupPacket, &memDesc, (PULONG)&bytesTransferred); if (!NT_SUCCESS(status)) { KdPrint(("SendControlTransfer failed %!STATUS!", status)); break; } break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } WdfRequestCompleteWithInformation(Request, status, bytesTransferred); return; }
NTSTATUS Acpi_EvaluateUcsiDsm ( _In_ PACPI_CONTEXT AcpiCtx, _In_ ULONG FunctionIndex, _Outptr_opt_ PACPI_EVAL_OUTPUT_BUFFER* Output ) /*++ N.B. Caller is expected to free the Output buffer. --*/ { NTSTATUS status; WDFDEVICE device; WDFMEMORY inputMemory; WDF_MEMORY_DESCRIPTOR inputMemDesc; PACPI_EVAL_INPUT_BUFFER_COMPLEX inputBuffer; size_t inputBufferSize; size_t inputArgumentBufferSize; PACPI_METHOD_ARGUMENT argument; WDF_MEMORY_DESCRIPTOR outputMemDesc; PACPI_EVAL_OUTPUT_BUFFER outputBuffer; size_t outputBufferSize; size_t outputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES attributes; WDF_REQUEST_SEND_OPTIONS sendOptions; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); device = Context_GetWdfDevice(AcpiCtx); inputMemory = WDF_NO_HANDLE; outputBuffer = nullptr; inputArgumentBufferSize = ACPI_METHOD_ARGUMENT_LENGTH(sizeof(GUID)) + ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) + ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) + ACPI_METHOD_ARGUMENT_LENGTH(0); inputBufferSize = FIELD_OFFSET(ACPI_EVAL_INPUT_BUFFER_COMPLEX, Argument) + inputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, inputBufferSize, &inputMemory, (PVOID*) &inputBuffer); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate failed for %Iu bytes - %!STATUS!", device, inputBufferSize, status); goto Exit; } RtlZeroMemory(inputBuffer, inputBufferSize); inputBuffer->Signature = ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE; inputBuffer->Size = (ULONG) inputArgumentBufferSize; inputBuffer->ArgumentCount = 4; inputBuffer->MethodNameAsUlong = (ULONG) 'MSD_'; argument = &(inputBuffer->Argument[0]); ACPI_METHOD_SET_ARGUMENT_BUFFER(argument, &GUID_UCSI_DSM, sizeof(GUID_UCSI_DSM)); argument = ACPI_METHOD_NEXT_ARGUMENT(argument); ACPI_METHOD_SET_ARGUMENT_INTEGER(argument, UCSI_DSM_REVISION); argument = ACPI_METHOD_NEXT_ARGUMENT(argument); ACPI_METHOD_SET_ARGUMENT_INTEGER(argument, FunctionIndex); argument = ACPI_METHOD_NEXT_ARGUMENT(argument); argument->Type = ACPI_METHOD_ARGUMENT_PACKAGE_EX; argument->DataLength = 0; outputArgumentBufferSize = ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)); outputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + outputArgumentBufferSize; outputBuffer = (PACPI_EVAL_OUTPUT_BUFFER) ExAllocatePoolWithTag(NonPagedPoolNx, outputBufferSize, TAG_UCSI); if (outputBuffer == nullptr) { status = STATUS_INSUFFICIENT_RESOURCES; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ExAllocatePoolWithTag failed for %Iu bytes", device, outputBufferSize); goto Exit; } RtlZeroMemory(outputBuffer, outputBufferSize); WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&inputMemDesc, inputMemory, NULL); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputMemDesc, outputBuffer, (ULONG) outputBufferSize); WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(UCSI_DSM_EXECUTION_TIMEOUT_IN_MS)); status = WdfIoTargetSendInternalIoctlSynchronously( WdfDeviceGetIoTarget(device), NULL, IOCTL_ACPI_EVAL_METHOD, &inputMemDesc, &outputMemDesc, &sendOptions, NULL); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] IOCTL_ACPI_EVAL_METHOD for _DSM failed - %!STATUS!", device, status); goto Exit; } if (outputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI_EVAL_OUTPUT_BUFFER signature is incorrect", device); status = STATUS_ACPI_INVALID_DATA; goto Exit; } Exit: if (inputMemory != WDF_NO_HANDLE) { WdfObjectDelete(inputMemory); } if (!NT_SUCCESS(status) || (Output == nullptr)) { if (outputBuffer) { ExFreePoolWithTag(outputBuffer, TAG_UCSI); } } else { *Output = outputBuffer; } TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); return status; }
NTSTATUS Acpi_EvaluatePld ( _In_ PACPI_CONTEXT AcpiCtx, _In_ LPCSTR DeviceName, _Out_ PACPI_PLD_BUFFER PldBuffer ) { NTSTATUS status; WDFDEVICE device; WDF_MEMORY_DESCRIPTOR inputMemDesc; ACPI_EVAL_INPUT_BUFFER_EX inputBuffer; size_t inputBufferSize; WDFMEMORY outputMemory; WDF_MEMORY_DESCRIPTOR outputMemDesc; PACPI_EVAL_OUTPUT_BUFFER outputBuffer; size_t outputBufferSize; size_t outputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES attributes; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); device = Context_GetWdfDevice(AcpiCtx); outputMemory = WDF_NO_HANDLE; inputBufferSize = sizeof(inputBuffer); RtlZeroMemory(&inputBuffer, inputBufferSize); inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE_EX; status = RtlStringCchPrintfA(inputBuffer.MethodName, sizeof(inputBuffer.MethodName), "%s._PLD", DeviceName); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] RtlStringCchPrintfA for creating method name failed - %!STATUS!", device, status); goto Exit; } outputArgumentBufferSize = 1024; outputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + outputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, outputBufferSize, &outputMemory, (PVOID*) &outputBuffer); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate failed for %Iu bytes - %!STATUS!", device, outputBufferSize, status); goto Exit; } RtlZeroMemory(outputBuffer, outputBufferSize); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputMemDesc, &inputBuffer, (ULONG) inputBufferSize); WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&outputMemDesc, outputMemory, NULL); status = WdfIoTargetSendInternalIoctlSynchronously( WdfDeviceGetIoTarget(device), NULL, IOCTL_ACPI_EVAL_METHOD_EX, &inputMemDesc, &outputMemDesc, NULL, NULL); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] IOCTL_ACPI_EVAL_METHOD_EX for %s failed - %!STATUS!", device, inputBuffer.MethodName, status); goto Exit; } if (outputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI_EVAL_OUTPUT_BUFFER signature is incorrect", device); goto Exit; } if (outputBuffer->Count < 1) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _PLD for %s didn't return anything", device, inputBuffer.MethodName); goto Exit; } if (outputBuffer->Argument[0].Type != ACPI_METHOD_ARGUMENT_BUFFER) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _PLD for %s returned an unexpected argument of type %d", device, inputBuffer.MethodName, outputBuffer->Argument[0].Type); goto Exit; } if (outputBuffer->Argument[0].DataLength < sizeof(*PldBuffer)) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] Unexpected _PLD buffer size for %s. Expected %Iu bytes, got %Iu bytes", device, inputBuffer.MethodName, sizeof(*PldBuffer), outputBuffer->Argument[0].DataLength); goto Exit; } *PldBuffer = *((PACPI_PLD_BUFFER) outputBuffer->Argument[0].Data); Exit: if (outputMemory != WDF_NO_HANDLE) { WdfObjectDelete(outputMemory); } TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); return status; }
static NTSTATUS CyGetUSB30DeviceConfiguration(__in PDEVICE_CONTEXT pDevContext,WDFMEMORY *pUsb30DeviceConfig) {/* WdfUsbTargetDeviceRetrieveConfigDescriptor function return the selected interface detail while the WdfUsbTargetDeviceFormatRequestForControlTransfer function return the device whole configuration(including the multiple interface) which is we don't want, adding specific implementation for the getting configuration descriptor here*/ USHORT ConfigLen = 0; PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL; WDF_OBJECT_ATTRIBUTES objectAttribs; NTSTATUS NtStatus =STATUS_SUCCESS; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_MEMORY_DESCRIPTOR tmpmemoryDescriptor; WDF_MEMORY_DESCRIPTOR tmpmemoryDescriptor1; USB_CONFIGURATION_DESCRIPTOR UsbConfigDec; CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Start CyGetUSB30DeviceConfiguration\n"); // first get the configuration length //Initialze the buffer WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&tmpmemoryDescriptor, (PVOID) &UsbConfigDec, sizeof(USB_CONFIGURATION_DESCRIPTOR)); //Initialize control setup packet to get total configuration length. controlSetupPacket.Packet.bm.Request.Dir = BmRequestDeviceToHost ; controlSetupPacket.Packet.bm.Request.Type = BmRequestStandard; controlSetupPacket.Packet.bm.Request.Recipient = BmRequestToDevice; controlSetupPacket.Packet.bRequest = USB_REQUEST_GET_DESCRIPTOR; controlSetupPacket.Packet.wIndex.Bytes.HiByte = 0; controlSetupPacket.Packet.wIndex.Bytes.LowByte = 0; controlSetupPacket.Packet.wValue.Bytes.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; controlSetupPacket.Packet.wValue.Bytes.LowByte =0; controlSetupPacket.Packet.wLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); NtStatus = WdfUsbTargetDeviceSendControlTransferSynchronously( pDevContext->CyUsbDevice, WDF_NO_HANDLE, NULL, &controlSetupPacket, &tmpmemoryDescriptor, NULL ); if (!NT_SUCCESS(NtStatus)) { CyTraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfUsbTargetDeviceSendControlTransferSynchronously failed:%x \n",NtStatus); CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "End CyGetUSB30DeviceConfiguration\n"); return NtStatus; } // allocate memory to get the device configuration WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs); objectAttribs.ParentObject = pDevContext->CyUsbDevice; // This object will be deleted after NtStatus = WdfMemoryCreate( &objectAttribs, NonPagedPool, CYMEM_TAG, UsbConfigDec.wTotalLength, pUsb30DeviceConfig, (PVOID)&configurationDescriptor ); if (!NT_SUCCESS(NtStatus)) { CyTraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfMemoryCreate failed:%x \n",NtStatus); CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "End CyGetUSB30DeviceConfiguration\n"); return NtStatus; } WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&tmpmemoryDescriptor1, *pUsb30DeviceConfig, NULL); //Get whole device configuration using the wTotalLenght od configuration descriptor //Initialize control setup packet to get total configuration length. controlSetupPacket.Packet.bm.Request.Dir = BmRequestDeviceToHost ; controlSetupPacket.Packet.bm.Request.Type = BmRequestStandard; controlSetupPacket.Packet.bm.Request.Recipient = BmRequestToDevice ; controlSetupPacket.Packet.bRequest = USB_REQUEST_GET_DESCRIPTOR; controlSetupPacket.Packet.wIndex.Bytes.HiByte = 0; controlSetupPacket.Packet.wIndex.Bytes.LowByte = 0; controlSetupPacket.Packet.wValue.Bytes.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; controlSetupPacket.Packet.wValue.Bytes.LowByte =0; controlSetupPacket.Packet.wLength = UsbConfigDec.wTotalLength; NtStatus = WdfUsbTargetDeviceSendControlTransferSynchronously( pDevContext->CyUsbDevice, WDF_NO_HANDLE, NULL, &controlSetupPacket, &tmpmemoryDescriptor1, NULL ); if (!NT_SUCCESS(NtStatus)) { CyTraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfUsbTargetDeviceSendControlTransferSynchronously failed:%x \n",NtStatus); CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "End CyGetUSB30DeviceConfiguration\n"); return NtStatus; } CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "End CyGetUSB30DeviceConfiguration\n"); return NtStatus; }