[wdmaudiodev] Simple loopback audio driver

  • From: Олег Герасимчук <supportaview@xxxxxxxxx>
  • To: wdmaudiodev@xxxxxxxxxxxxx
  • Date: Mon, 7 Mar 2016 17:56:31 +0200

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: