none
Fail to get a meaningful return value from the DeviceIoControl request of IOCTL_SERIAL_GET_BAUD_RATE RRS feed

  • Question

  • Dear Sir:

    I am developing a peripheral driver of 8051 that is permanently connected to a serial port within a Win8.1 tablet.

    While reading the following descriptions, please associate it with the code.

    When CMyQueue::OnDeviceIoControl was invoked to get the current baud rate, the return value of the baud rate was always 0. It was extracted from the output memory object and stored in the baudRateBuffer variable. And i was watching this variable when debuging.

    Besides, if we incorporated WDF_REQUEST_SEND_OPTION_TIMEOUT into pWdfRequest->Send, the result of spParams->GetCompletionStatus() will be 0xC00000B5(STATUS_IO_TIMEOUT).

    The questions are:
    1. Why the return value of the baud rate was always 0. Its value should be 115200 from our ACPI configuration descriptor.
    2. Why 0xC00000B5(STATUS_IO_TIMEOUT) occurrd.
    3. Do we need to incorporate WDF_REQUEST_SEND_OPTION_TIMEOUT into pWdfRequest->Send?

    Thanks for any advice.

    Sincerely

    Zale Yu

    VOID
    STDMETHODCALLTYPE
    CMyQueue::OnDeviceIoControl(
    _In_ IWDFIoQueue *pWdfQueue,
    _In_ IWDFIoRequest *pWdfRequest,
    _In_ ULONG ControlCode,
    _In_ SIZE_T InputBufferSizeInBytes,
    _In_ SIZE_T OutputBufferSizeInBytes
    )
    /*++
    
    Routine Description:
    
    
    DeviceIoControl dispatch routine
    
    Arguments:
    
    pWdfQueue - Framework Queue instance
    pWdfRequest - Framework Request  instance
    ControlCode - IO Control Code
    InputBufferSizeInBytes - Length of input buffer
    OutputBufferSizeInBytes - Length of output buffer
    
    Always succeeds DeviceIoIoctl
    Return Value:
    
    VOID
    
    --*/
    {
        UNREFERENCED_PARAMETER(OutputBufferSizeInBytes);
        UNREFERENCED_PARAMETER(InputBufferSizeInBytes);
        UNREFERENCED_PARAMETER(pWdfQueue);
    
        HRESULT hr = S_OK;
        SIZE_T reqCompletionInfo = 0;
        IWDFMemory *inputMemory = NULL;
        IWDFMemory *outputMemory = NULL;
    
        WUDF_TEST_DRIVER_ASSERT(pWdfRequest);
        WUDF_TEST_DRIVER_ASSERT(m_Device);
    
        pWdfRequest->GetInputMemory(&inputMemory);
        pWdfRequest->GetOutputMemory(&outputMemory);
    
        if (NULL == inputMemory)
        {
            hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
        }
        if (NULL == outputMemory)
        {
            hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
        }
        // Format request
        if (SUCCEEDED(hr))
        {
            hr = m_Device->m_spRemoteTarget->FormatRequestForIoctl(
                pWdfRequest,
                ControlCode,
                NULL,
                inputMemory,
                NULL,
                outputMemory,
                NULL);
    
            if (FAILED(hr))
            {
                // Error handling
            }
        }
    
        // Send down the request
        if (SUCCEEDED(hr))
        {
            // Note 1: if we include WDF_REQUEST_SEND_OPTION_TIMEOUT, 
            // the result of spParams->GetCompletionStatus() will be 0xC00000B5(STATUS_IO_TIMEOUT).
            hr = pWdfRequest->Send(
                m_Device->m_spRemoteTarget,
                (WDF_REQUEST_SEND_OPTION_SYNCHRONOUS),//| WDF_REQUEST_SEND_OPTION_TIMEOUT
                0);
    
            if (FAILED(hr))
            {
                //Trace(
                //    TRACE_LEVEL_ERROR,
                //    "Failed to send the WDF request, %!HRESULT!",
                //    hr);
            }
        }
        SERIAL_BAUD_RATE baudRateBuffer = { 0 };
        if (ControlCode == IOCTL_SERIAL_GET_BAUD_RATE)
        {
            if (SUCCEEDED(hr))
            {
                hr = outputMemory->CopyFromBuffer(0,
                    (void*)&baudRateBuffer,
                    sizeof(SERIAL_BAUD_RATE));
            }
        }
        // get the result
        if (SUCCEEDED(hr))
        {
            IWDFRequestCompletionParams* spParams = nullptr;
            pWdfRequest->GetCompletionParams(&spParams);
    
            hr = spParams->GetCompletionStatus();
    
            if (SUCCEEDED(hr))
            {                       
                reqCompletionInfo = spParams->GetInformation();
            }
        }
        //
        // clean up
        //
        if (inputMemory)
        {
            inputMemory->Release();
        }
    
        if (outputMemory)
        {
            outputMemory->Release();
        }
        //
        // complete the request
        //
        pWdfRequest->CompleteWithInformation(hr, reqCompletionInfo);
    
        return;
    }



    • Edited by Zale Yu Tuesday, May 13, 2014 11:46 AM
    Tuesday, May 13, 2014 11:38 AM