[wdmaudiodev] Re: Simple loopback audio driver

  • From: Matthew van Eerde <Matthew.van.Eerde@xxxxxxxxxxxxx>
  • To: Олег Герасимчук <supportaview@xxxxxxxxx>, "wdmaudiodev@xxxxxxxxxxxxx" <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Mon, 7 Mar 2016 16:34:28 +0000

The dump file should tell you.

From: Олег Герасимчук<mailto:supportaview@xxxxxxxxx>
Sent: Monday, March 7, 2016 7:57 AM
To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx>
Subject: [wdmaudiodev] Simple loopback audio driver

Hello, everyone!
I wrote some simple virtual audio driver based on MSVAD Simple example. It just 
copying data from its wave out pin (speakers) to its microphone. It works fine, 
but sometimes my driver crash on my Windows (Win 7 x64 SP1 Build 7601).
Here is what I just changed (basedma.cpp) in an example:

In AllocateBuffer function:

STDMETHODIMP_(NTSTATUS)
CMiniportWaveCyclicStreamMSVAD::AllocateBuffer
(
    IN ULONG                    BufferSize,
    IN PPHYSICAL_ADDRESS        PhysicalAddressConstraint OPTIONAL
)
{
...
// My code
    if (ntStatus == STATUS_SUCCESS && m_pvSharedBuffer == NULL) {
        m_pvSharedBuffer = (PVOID) ExAllocatePoolWithTag(NonPagedPool, 
BufferSize, 'VOG');
        if (!m_pvSharedBuffer) {
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        } else {
            m_ulSharedBufferSize = BufferSize;
            m_pvSharedBufferCur = m_pvSharedBuffer;
        }
    }
// My code
}

In CopyFrom function (copying data from the internal buffer):

STDMETHODIMP_(void)
CMiniportWaveCyclicStreamMSVAD::CopyFrom
(
    IN  PVOID                   Destination,
    IN  PVOID                   Source,
    IN  ULONG                   ByteCount
)
{
// My code
    if (m_pvSharedBuffer != NULL) {
        SIZE_T szFillSize = (PUCHAR) m_pvSharedBufferCur - (PUCHAR) 
m_pvSharedBuffer;
        if (ByteCount >= szFillSize) {
            RtlCopyMemory(Destination, m_pvSharedBuffer, szFillSize);
            m_pvSharedBufferCur = m_pvSharedBuffer;
        } else {
            RtlCopyMemory(Destination, m_pvSharedBuffer, ByteCount);
            PUCHAR pcNewBeginning = (PUCHAR) m_pvSharedBuffer + ByteCount;
            SIZE_T szNewSize = szFillSize-ByteCount;
            RtlMoveMemory(m_pvSharedBuffer, pcNewBeginning, szNewSize);
            m_pvSharedBufferCur = (PUCHAR) m_pvSharedBuffer + szNewSize;
        }
    }
// My code
}

In CopyTo function (copying data to the internal buffer):

STDMETHODIMP_(void)
CMiniportWaveCyclicStreamMSVAD::CopyTo
(
    IN  PVOID                   Destination,
    IN  PVOID                   Source,
    IN  ULONG                   ByteCount
)
{
// My code
    if (m_pvSharedBuffer != NULL) {
        if (ByteCount > m_ulSharedBufferSize) {
            // if incoming data is larger than internal buffer
            Source = (PUCHAR) Source + (ByteCount-m_ulSharedBufferSize);
            ByteCount = m_ulSharedBufferSize;
            m_pvSharedBufferCur = m_pvSharedBuffer;
        } else {
            SIZE_T szFillSize = (PUCHAR) m_pvSharedBufferCur - (PUCHAR) 
m_pvSharedBuffer;
            SIZE_T szBytesLeft = m_ulSharedBufferSize - szFillSize;

            if (szBytesLeft < ByteCount) {
                SIZE_T szMemShift = ByteCount-szBytesLeft;
                PUCHAR pcNewBeginning = (PUCHAR) m_pvSharedBuffer + szMemShift;
                szFillSize -= szMemShift;
                RtlMoveMemory(m_pvSharedBuffer, pcNewBeginning, szFillSize);
                m_pvSharedBufferCur = (PUCHAR) m_pvSharedBuffer + szFillSize;
            }
        }
        RtlCopyMemory(m_pvSharedBufferCur, Source, ByteCount);
        m_pvSharedBufferCur = (PUCHAR) m_pvSharedBufferCur + ByteCount;
    }
// My code
}

Also I removed everything related to saving data into the file (in the 
basewave.cpp). The following code was removed:

NTSTATUS
CMiniportWaveCyclicStreamMSVAD::Init
(
    IN  PCMiniportWaveCyclicMSVAD Miniport_,
    IN  ULONG                   Pin_,
    IN  BOOLEAN                 Capture_,
    IN  PKSDATAFORMAT           DataFormat_
)
{
...
        // If this is not the capture stream, create the output file.
        //
        if (!m_fCapture)
        {
            DPF(D_TERSE, ("SaveData %p", &m_SaveData));
            ntStatus = m_SaveData.SetDataFormat(DataFormat_);
            if (NT_SUCCESS(ntStatus))
            {
                ntStatus = m_SaveData.Initialize();
            }
        }
...
}

STDMETHODIMP_(NTSTATUS)
CMiniportWaveCyclicStreamMSVAD::SetFormat
(
    IN  PKSDATAFORMAT           Format
)
{
...
                if (!m_fCapture)
                {
                    ntStatus = m_SaveData.SetDataFormat(Format);
                }
...
}

STDMETHODIMP
CMiniportWaveCyclicStreamMSVAD::SetState
(
    IN  KSSTATE                 NewState
)
{
...
            // Wait until all work items are completed.
            //
            if (!m_fCapture)
            {
                m_SaveData.WaitAllWorkItems();
            }
...
}


So what I am doing wrong?

Other related posts: