none
ReadFile returning 1 for GetStatusError trying to read DMA data RRS feed

  • Question

  • Hello.

    I am trying to get DMA working on a KMDF driver that supports a custom board.

    I am using ReadFile with the handle for the device driver in my test application to obtain the data from the DMA.  Unfortunately, the ReadFile call fails and I get a 0x1 for the GetLastError() for the call.

    I pass in the handle to the driver and I have set up local buffers to receive any data.

    Any ideas on how to debug this?

    Thanks,

    Brian

    Tuesday, November 12, 2013 8:08 PM

Answers

  • Nothing interesting in the log, can you turn on verbose logging with wdfverifier.exe (on the machine under test) and repro to see if that gives any interesting info?

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Friday, November 15, 2013 7:38 PM

All replies

  • Well that is an "ERROR_INVALID_FUNCTION"  which in the kernel is typically STATUS_INVALID_FUNCTION, STATUS_NOT_IMPLEMENTED, or STATUS_INVALID_DEVICE_REQUEST (there are others).  So the first question is did you create an I/O queue with EvtIoRead set up? 

    To debug this you are going to need two machines (or two VM's) and Windbg.  You may be able to get a clue by adding a number of KdPrint statements and using DebugMon, but to really debug drivers you need Windbg (or the builtin equivalent in the WDK 8.0 or later).


    Don Burn Windows Filesystem and Driver Consulting Website: http://www.windrvr.com Blog: http://msmvps.com/blogs/WinDrvr

    Tuesday, November 12, 2013 8:23 PM
  • Don,

    I have implemented a read queue for the Request. I am using the Visual Studio 2013 RC for my build platform and debugger. I can make IOCTL calls to my driver. I put in the read queue so I could set up the dma and use ReadFile to obtain my data.

    Here is my code that sets up the queues. The first is for my IOCTL interface requests. The second is for the Read operations.   

     I added the Read queue this morning.   I borrowed the read queue code from the Plx9x5x project. I checked the status return codes from the calls and all returned OK.  So the ReadFile returning a 1 indicates the Read queue may not be setup correctly?

    Thanks,

    Brian

    WDFQUEUE queue;
        NTSTATUS status;
        WDF_IO_QUEUE_CONFIG    queueConfig;
    PDEVICE_CONTEXT   devContext;

        PAGED_CODE();

        //
        // Configure a default queue so that requests that are not
        // configure-forwarded using WdfDeviceConfigureRequestDispatching to goto
        // other queues get dispatched here.
        //
        WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
             &queueConfig,
            WdfIoQueueDispatchParallel
            );

        queueConfig.EvtIoDeviceControl = dts9080EvtIoDeviceControl;
        queueConfig.EvtIoStop = dts9080EvtIoStop;

        status = WdfIoQueueCreate(
                     Device,
                     &queueConfig,
                     WDF_NO_OBJECT_ATTRIBUTES,
                     &queue
                     );

        if( !NT_SUCCESS(status) ) {
            TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "WdfIoQueueCreate failed %!STATUS!", status);
            return status;
        }

    //

    //
    // Create a new IO Queue for IRP_MJ_READ requests in sequential mode.
    //
    WDF_IO_QUEUE_CONFIG_INIT(&queueConfig,
    WdfIoQueueDispatchSequential);

    queueConfig.EvtIoRead = Dts9080EvtIoRead;

    //
    // By default, Static Driver Verifier (SDV) displays a warning if it 
    // doesn't find the EvtIoStop callback on a power-managed queue. 
    // The 'assume' below causes SDV to suppress this warning. If the driver 
    // has not explicitly set PowerManaged to WdfFalse, the framework creates
    // power-managed queues when the device is not a filter driver.  Normally 
    // the EvtIoStop is required for power-managed queues, but for this driver
    // it is not needed b/c the driver doesn't hold on to the requests for 
    // long time or forward them to other drivers. 
    // If the EvtIoStop callback is not implemented, the framework waits for
    // all driver-owned requests to be done before moving in the Dx/sleep 
    // states or before removing the device, which is the correct behavior 
    // for this type of driver. If the requests were taking an indeterminate
    // amount of time to complete, or if the driver forwarded the requests
    // to a lower driver/another stack, the queue should have an 
    // EvtIoStop/EvtIoResume.
    //

    devContext = DeviceGetContext(Device);

    __analysis_assume(queueConfig.EvtIoStop != 0);
    status = WdfIoQueueCreate(Device,
    &queueConfig,
    WDF_NO_OBJECT_ATTRIBUTES,
    &devContext->ReadQueue);
    __analysis_assume(queueConfig.EvtIoStop == 0);

    if (!NT_SUCCESS(status)) {
    TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE,
    "WdfIoQueueCreate failed: %!STATUS!", status);
    return status;
    }

    //
    // Set the Read Queue forwarding for IRP_MJ_READ requests.
    //
    status = WdfDeviceConfigureRequestDispatching(Device,
    devContext->ReadQueue,
    WdfRequestTypeRead);

    if (!NT_SUCCESS(status)) {
    TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE,
    "DeviceConfigureRequestDispatching failed: %!STATUS!", status);
    return status;
    }



    Tuesday, November 12, 2013 8:49 PM
  • As far as I can tell, I am setting the queues up correctly.  I was setting the WdfDeviceInitSetIoType to WdfDeviceIoDirect. I have changed this setting to WdfDeviceIoNeither. My reasoning being that I am using buffers in the application to receive any data I get from the DMA operation with the ReadFile command.

    I have set a breakpoint at the EvtIoRead routine. I expect to hit this if the ReadFile call works. I am not hitting this breakpoint when I try to execute ReadFile. 

    Ideas?

    Thanks,

    Brian

     

    Wednesday, November 13, 2013 3:01 PM
  • Are you passing a zero buffer length to ReadFile in user mode?

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, November 13, 2013 3:39 PM
  • Here is my code:

    char buffer[1024];

    DWORD read;

    if (!ReadFile (hDevice, buffer, 1024, &read, 0) )

    {

    DWORD err = GetLastError();

    int y = 0;

    }

    Seems simple enough. I verified I had the same handle that I used on the CreateFile call.

    I get err = 1 on the call. I tried walking into the ReadFile in assembly but there is an ocean of code there. 

    My goal is to see if the read queue is getting the request and I get a call at EvtIoRead.

    I am not sure how to debug this or where to start.

    Thanks,

    Brian

    Wednesday, November 13, 2013 4:14 PM
  • Run !wdfkd.wdfdevicequeues <your WDFDEVICE> to see that your queues are created the way you think they are. furthermore, look very carefully at the state of the read queue and it says "Can accept", "Can dispatch" and if power managed, PowerOn

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, November 13, 2013 5:54 PM
  • also, immediately after the failed read, run !wdfk.wdflogdump <your driver name> and see if the read was failed by KMDF and reported in the log

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, November 13, 2013 5:55 PM
  • Doron,

    I am trying to run the !wdfkd.wdfdevicequeues <handle> command right after creating the queues. I am using the 64 bit hex value for the Device handle.

    I am getting a message that says I am not using the correct symbols. I have set the .sympath to point to the .pdb file that is generated for the device driver. Also tried a path to the wdf010013.tmh file in the tools for 8.1 unsuccessfully. What path should i be using?

    Thanks,

    Brian


    Thursday, November 14, 2013 8:56 PM
  • Also, my _NT_SYMBOL_PATH is set to the source code directory for my driver. I also copied the *.pdb file into the source code directory and i am still getting this error.

    Cheers,

    Brian

    Thursday, November 14, 2013 10:10 PM
  • Up to this point, I haven't had to load system symbols to debug my driver. Sounds like that time is here.

    Brian

    Friday, November 15, 2013 1:53 PM
  • Point your symbol path to the MSFT public symbol server

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Friday, November 15, 2013 4:26 PM
  • Doron,

    I have the wdfkd commands working and I ran the two commands you suggested. I do not see any mention of IRP_MJ_READ or any read operation. That must mean the ReadFile is failing prior to the KMDF code. Correct?

    Thanks,

    Brian

    There are 29 log entries
    --- start of log ---
    1: FxIFRStart - FxIFR logging started
    2: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering PnP State WdfDevStatePnpInit from WdfDevStatePnpObjectCreated
    3: FxPkgPnp::Dispatch - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20, IRP_MJ_PNP, 0x00000000(IRP_MN_START_DEVICE) IRP 0xFFFFE00005189680
    4: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering PnP State WdfDevStatePnpInitStarting from WdfDevStatePnpInit
    5: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering PnP State WdfDevStatePnpHardwareAvailable from WdfDevStatePnpInitStarting
    6: FxPkgPnp::PnpMatchResources - Not enough interrupt objects created by WDFDEVICE 0x00001FFFFE60EE68
    7: FxInterrupt::AssignResources - Is MSI? 0, MSI-ID 0, AffinityPolicy WdfIrqPolicyOneCloseProcessor, Priority WdfIrqPriorityUndefined, Group 0, Affinity 0x3, Irql 0xa, Vector 0xa2
    8: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering power policy state WdfDevStatePwrPolStarting from WdfDevStatePwrPolObjectCreated
    9: FxPowerIdleMachine::ProcessEventLocked - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering power idle state FxIdleStarted from FxIdleStopped
    10: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering Power State WdfDevStatePowerStartingCheckDeviceType from WdfDevStatePowerObjectCreated
    11: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering Power State WdfDevStatePowerD0Starting from WdfDevStatePowerStartingCheckDeviceType
    12: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering Power State WdfDevStatePowerD0StartingConnectInterrupt from WdfDevStatePowerD0Starting
    13: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering Power State WdfDevStatePowerD0StartingDmaEnable from WdfDevStatePowerD0StartingConnectInterrupt
    14: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering Power State WdfDevStatePowerD0StartingStartSelfManagedIo from WdfDevStatePowerD0StartingDmaEnable
    15: FxPkgIo::ResumeProcessingForPower - Power resume all queues of WDFDEVICE 0x00001FFFFE60EE68
    16: FxPowerIdleMachine::ProcessEventLocked - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering power idle state FxIdleStartedPowerUp from FxIdleStarted
    17: FxPowerIdleMachine::ProcessEventLocked - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering power idle state FxIdleDisabled from FxIdleStartedPowerUp
    18: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering Power State WdfDevStatePowerDecideD0State from WdfDevStatePowerD0StartingStartSelfManagedIo
    19: FxPkgPnp::PowerEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering Power State WdfDevStatePowerD0 from WdfDevStatePowerDecideD0State
    20: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering power policy state WdfDevStatePwrPolStartingPoweredUp from WdfDevStatePwrPolStarting
    21: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering power policy state WdfDevStatePwrPolStartingSucceeded from WdfDevStatePwrPolStartingPoweredUp
    22: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering power policy state WdfDevStatePwrPolStartingDecideS0Wake from WdfDevStatePwrPolStartingSucceeded
    23: FxPkgPnp::PowerPolicyEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering power policy state WdfDevStatePwrPolStarted from WdfDevStatePwrPolStartingDecideS0Wake
    24: FxPowerIdleMachine::ProcessEventLocked - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering power idle state FxIdleDisabled from FxIdleDisabled
    25: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering PnP State WdfDevStatePnpEnableInterfaces from WdfDevStatePnpHardwareAvailable
    26: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 entering PnP State WdfDevStatePnpStarted from WdfDevStatePnpEnableInterfaces
    27: FxPkgPnp::Dispatch - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20, IRP_MJ_PNP, 0x00000014(IRP_MN_QUERY_PNP_DEVICE_STATE) IRP 0xFFFFE00005189680
    28: FxPkgFdo::HandleQueryPnpDeviceStateCompletion - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20 returning PNP_DEVICE_STATE 0x0 IRP 0xFFFFE00005189680
    29: FxPkgPnp::Dispatch - WDFDEVICE 0x00001FFFFE60EE68 !devobj 0xFFFFE000043BBE20, IRP_MJ_PNP, 0x00000007(IRP_MN_QUERY_DEVICE_RELATIONS) type BusRelations IRP 0xFFFFE00005189680
    ---- end of log ----

    Friday, November 15, 2013 7:16 PM
  • Nothing interesting in the log, can you turn on verbose logging with wdfverifier.exe (on the machine under test) and repro to see if that gives any interesting info?

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Friday, November 15, 2013 7:38 PM
  • I have never used Wdfverifier before. I copied it from the Windows 8.1 tools (x64) to my machine under test.

    Here is my configuration:

    Host machine (Windows 7) is running VS 2013 RC debugging the driver remotely.

    target Machine (Windows 8.1). I am using a Visual Studio 2012 test environment and test program to open my driver and send commands to it. I open the driver, send some IOCTL's to the driver to configure the hardware and then I try to execute a ReadFile command. I am expecting the ReadFile command to ultimately send a read Request to my driver. 

    Now, I ran Wdfverifier on the target machine.  I am not sure how this ties in with my environment. There is a KMDF verifier setting on my host machine for my driver. Should I be using that instead? I don't see where the output should go.

    Brian

     

    Friday, November 15, 2013 8:39 PM
  • You can use the kmdf verifier settings in VS too. Enable verbose logging either way. The verbose logs will show up in wdflogdump

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Saturday, November 16, 2013 3:10 AM