Ejemplo n.º 1
1
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;
}
Ejemplo n.º 2
0
VOID
SDVTest_wdf_MemoryAfterReqCompletionIntIoctlAdd(
    _In_  WDFMEMORY   Memory
    )
{
    WDF_MEMORY_DESCRIPTOR   memoryDescriptor;

    WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memoryDescriptor, Memory, NULL);

    return;
}
Ejemplo n.º 3
0
///////////////////////////////////////////////////////////////////////////////
//
//  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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}