none
KMDF WdfEvtIoWrite issue RRS feed

  • Question

  • I have a skeleton KMDF driver with WdfEvtIoWrite routine. I can load the driver using INF,  call CreateFile() on the device from a user mode app and get a handle to the device. But when the call WriteFile() I get a bug check. On analysing crash dump, I get the following. I think the below is the relevant portion of the dump anlysis.

    EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
    
    FAULTING_IP: 
    SoftwareOnlyKMDFDriver+1df1
    fffff880`03e9ddf1 48833800        cmp     qword ptr [rax],0
    
    CONTEXT:  fffff88002204db0 -- (.cxr 0xfffff88002204db0)
    rax=0000000000000000 rbx=fffffa80020a8a70 rcx=fffffa80015fd0ea
    rdx=0000000000000000 rsi=fffffa80015fbe40 rdi=fffffa80015fe420
    rip=fffff88003e9ddf1 rsp=fffff88002205790 rbp=fffff88002205820
     r8=0000000000000000  r9=0000000000000000 r10=000000000000000a
    r11=fffff880022056b0 r12=0000057ffdf57588 r13=0000000000000000
    r14=0000057ffea01bd8 r15=0000000000000005
    iopl=0         nv up ei ng nz na po nc
    cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00010286
    SoftwareOnlyKMDFDriver+0x1df1:
    fffff880`03e9ddf1 48833800        cmp     qword ptr [rax],0 ds:002b:00000000`00000000=????????????????
    Resetting default scope
    
    DEFAULT_BUCKET_ID:  WIN7_DRIVER_FAULT
    
    BUGCHECK_STR:  0x3B
    
    PROCESS_NAME:  KMDFDriverClie
    
    CURRENT_IRQL:  2
    
    LAST_CONTROL_TRANSFER:  from fffff88000e20ece to fffff88003e9ddf1
    
    STACK_TEXT:  
    fffff880`02205790 fffff880`00e20ece : 0000057f`fea01bd8 0000057f`fdf57588 00000000`00000005 00000000`00000000 : SoftwareOnlyKMDFDriver+0x1df1
    fffff880`022057e0 fffff880`00e2042f : fffffa80`015fe400 fffff880`022058a0 fffffa80`015fe420 00000000`00000001 : Wdf01000!FxIoQueue::DispatchRequestToDriver+0x3ce
    fffff880`02205860 fffff880`00e2bfbb : fffffa80`015fbe40 fffffa80`020a8a00 00000000`00000000 fffffa80`020a8a70 : Wdf01000!FxIoQueue::DispatchEvents+0x66f
    fffff880`022058e0 fffff880`00e2530a : fffffa80`015fbe00 fffffa80`020a8a70 fffffa80`02390010 fffff880`022059c0 : Wdf01000!FxIoQueue::QueueRequest+0x2ab
    fffff880`02205950 fffff880`00e249da : fffffa80`020a8a70 fffffa80`02390010 fffffa80`024d2d20 fffffa80`02390010 : Wdf01000!FxPkgIo::Dispatch+0x4da
    fffff880`022059c0 fffff880`00e24aa6 : fffffa80`02390010 fffffa80`024d2d20 fffffa80`015fec70 fffffa80`015fec01 : Wdf01000!FxDevice::Dispatch+0x19a
    fffff880`02205a00 fffff800`02bea71b : 00000000`00000001 fffffa80`024d2d20 00000000`00000001 fffffa80`02390010 : Wdf01000!FxDevice::DispatchWithLock+0xa6
    fffff880`02205a40 fffff800`02bf5183 : fffffa80`02390170 fffffa80`024d2d70 fffffa80`024d2d20 fffff800`02a54e80 : nt!IopSynchronousServiceTail+0xfb
    fffff880`02205ab0 fffff800`028e18d3 : fffff880`02205c01 00000000`00000000 00000000`00000000 00000000`00000000 : nt!NtWriteFile+0x7e2
    fffff880`02205bb0 00000000`75252e09 : 00000000`752529f5 00000000`771c129a 00000000`752c0023 00000000`00000246 : nt!KiSystemServiceCopyEnd+0x13
    00000000`0008e9a8 00000000`752529f5 : 00000000`771c129a 00000000`752c0023 00000000`00000246 00000000`0018e748 : wow64cpu!CpupSyscallStub+0x9
    00000000`0008e9b0 00000000`752cd07e : 00000000`00000000 00000000`75251920 00000000`0008ec40 00000000`7773ecd1 : wow64cpu!ReadWriteFileFault+0x31
    00000000`0008ea70 00000000`752cc549 : 00000000`00000000 00000000`00000000 00000000`752c4ac8 00000000`7ffe0030 : wow64!RunCpuSimulation+0xa
    00000000`0008eac0 00000000`77754956 : 00000000`00362e60 00000000`00000000 00000000`77842670 00000000`77815978 : wow64!Wow64LdrpInitialize+0x429
    00000000`0008f010 00000000`77751a17 : 00000000`00000000 00000000`77754061 00000000`0008f5c0 00000000`00000000 : ntdll!LdrpInitializeProcess+0x17e4
    00000000`0008f500 00000000`7773c32e : 00000000`0008f5c0 00000000`00000000 00000000`7efdf000 00000000`00000000 : ntdll! ?? ::FNODOBFM::`string'+0x29220
    00000000`0008f570 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!LdrInitializeThunk+0xe

    Below is the driver WdfEvtIoWrite() handler.

    typedef struct _WDF_QUEUE_CONTEXT
    {
    PVOID RequestBuffer;
    ULONG BufferLength;
    WDFTIMER WdfTimer;
    WDFREQUEST CurrentRequest;
    NTSTATUS CurrentRequestStatus;
    }WDF_QUEUE_CONTEXT,*PWDF_QUEUE_CONTEXT;

    WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WDF_QUEUE_CONTEXT, WDFQueueGetCotext);

    VOID WdfEvtIoWrite( WDFQUEUE Queue, WDFREQUEST Request, size_t Length ) // Length -> Number of bytes to write. { WDFMEMORY WdfMemory; NTSTATUS status; PWDF_QUEUE_CONTEXT QueueContext; KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "<--DRIVER-->Entering SoftwareOnlyWdfDriver::WdfEvtIoWrite\r\n" )); // Get the handle to framework memory object of the incoming request object. The Request object contains data to be written. status = WdfRequestRetrieveInputMemory( Request, &WdfMemory ); if( !NT_SUCCESS( status )) { KdPrintEx( (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "<--DRIVER-->Failed to get handle to framework memory object of the incoming request in SoftwareOnlyWdfDriver::WdfDeviceAdd\r\n" )); return; } // Get the WDF Queue Context of the current request. This is done via the accesor method. QueueContext = WDFQueueGetCotext(Queue ); // If previous buffer has been set, free it. if( 0 != QueueContext->RequestBuffer ) { ExFreePool( QueueContext->RequestBuffer ); QueueContext->RequestBuffer = 0; QueueContext->BufferLength = 0; } // Allocate new buffer for the driver . The buffer size is the length. QueueContext->RequestBuffer = ExAllocatePoolWithTag(NonPagedPool, Length,'POOL'); if( 0 == QueueContext->RequestBuffer ) { KdPrintEx( (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "<--DRIVER-->Failed to allocate pool memory in SoftwareOnlyWdfDriver::WdfEvtIoWrite\r\n" )); return; } // Copy the data to be written from the Request memory buffer to the newly allocated driver buffer. status = WdfMemoryCopyToBuffer( WdfMemory, 0, // Copy from the beginning of the memory. QueueContext->RequestBuffer, Length ); if( !NT_SUCCESS( status )) { KdPrintEx( (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "<--DRIVER-->Failed to copy memory to driver buffer in SoftwareOnlyWdfDriver::WdfEvtIoWrite\r\n" )); ExFreePool( QueueContext->RequestBuffer ); QueueContext->RequestBuffer = 0; QueueContext->BufferLength = 0; WdfRequestComplete( Request, status ); return; } // Transfer success. Set request complete infromation with the length of data transfered. WdfRequestSetInformation( Request, (ULONG_PTR)Length ); WdfRequestComplete( Request, status ); KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "<--DRIVER-->Leaving SoftwareOnlyWdfDriver::WdfEvtIoWrite\r\n" )); }

    I even tried WdfEvtIoWrite() with the statements commented out and with only the handler skeleton in place. The bug check still occurs. Below is how I invoke the driver.

    TCHAR* tszDevicePath = 0; if ( !GetDevicePath((LPGUID) &GUID_DEVINTERFACE_SoftwareOnlyKMDFDriver, tszDevicePath )) { AfxMessageBox(L"Failed to get device path of the device" ); return; } // Write data to device. DWORD dwReturn; DWORD dwErorCode; CString csMessage; m_hFile = CreateFile(tszDevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if( INVALID_HANDLE_VALUE == m_hFile ) { dwErorCode = GetLastError(); csMessage.Format(L"Driver# Error1 %d occured", dwErorCode ); OutputDebugString( csMessage ); AfxMessageBox( csMessage ); return; } AfxMessageBox(L"CreateFile success!!" ); char buffer[5] = {'\0'}; sprintf_s(buffer, "%s", "Data");

    // Bug checks here.

    if( FALSE == WriteFile(m_hFile, buffer, strlen(buffer), &dwReturn, NULL)) { AfxMessageBox( L"Write File failed" ); OutputDebugString( L"Driver# WriteFile failed" ); } else { AfxMessageBox( L"Write File success!!" ); OutputDebugString( L"Driver# WriteFile success" ); }

    GetDevicePath() and CreateFile() are success. I am not getting any clue on analysing the crash dump.



    • Edited by its_me_here Tuesday, January 7, 2014 7:16 PM
    Tuesday, January 7, 2014 7:10 PM

Answers

  • You have a null deref. It could be that you don't have a context on the queue object. Did you specify the content WDF_QUEUE_CONTEXT in the attributes structure when you created the queue?

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

    Tuesday, January 7, 2014 9:02 PM

All replies

  • It would help if you had the symbols for your driver loaded, so the !analyze would show the line that is failing.  Also, it might help if you posted the debug prints that occurred before you crashed.


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

    Tuesday, January 7, 2014 7:16 PM
  • You have a null deref. It could be that you don't have a context on the queue object. Did you specify the content WDF_QUEUE_CONTEXT in the attributes structure when you created the queue?

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

    Tuesday, January 7, 2014 9:02 PM
  • Thank you Doron. That was the issue. I had not mentioned the queue attributes while creating the queue and had in fact set the WDF_OBJECT_ATTRIBUTES as WDF_NO_OBJECT_ATTRIBUTES. in WdfIoQueueCreate () method.

    Corrected as below

    WDF_OBJECT_ATTRIBUTES  queueAttributes;
    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queueAttributes, QUEUE_CONTEXT);
    queueAttributes.SynchronizationScope = WdfSynchronizationScopeQueue;
    queueAttributes.EvtDestroyCallback = EchoEvtIoQueueContextDestroy;
    status = WdfIoQueueCreate(
                     Device,
                     &queueConfig,
    				&queueAttributes,
                     &queue
                     );
    

    Friday, January 10, 2014 9:58 AM