📄 minwave.cpp
字号:
PAGED_CODE();
ASSERT(OutStream);
ASSERT(DataFormat);
ASSERT(OutDmaChannel);
ASSERT(OutServiceGroup);
DPF_ENTER(("[CMiniportWaveCyclic::NewStream]"));
NTSTATUS ntStatus = STATUS_SUCCESS;
PCMiniportWaveCyclicStream stream = NULL;
// Determine if the format is valid.
//
if (NT_SUCCESS(ntStatus))
{
ntStatus = ValidateFormat(DataFormat);
}
// Check if we have enough streams.
if (Capture)
{
if (m_fCaptureAllocated)
{
DPF(D_TERSE, ("[Only one capture stream supported]"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
if (m_fAc3RenderAllocated && IsFormatAc3(DataFormat))
{
DPF(D_TERSE, ("[Only one Ac3 render stream supported]"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
if (m_fPcmRenderAllocated && !IsFormatAc3(DataFormat))
{
DPF(D_TERSE, ("[Only one Pcm render stream supported]"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
}
// Instantiate a stream. Stream must be in
// NonPagedPool because of file saving.
//
if (NT_SUCCESS(ntStatus))
{
stream = new (NonPagedPool, MSVAD_POOLTAG)
CMiniportWaveCyclicStream(OuterUnknown);
if (stream)
{
stream->AddRef();
ntStatus =
stream->Init
(
this,
Pin,
Capture,
DataFormat
);
}
else
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
}
}
if (NT_SUCCESS(ntStatus))
{
if (Capture)
{
m_fCaptureAllocated = TRUE;
}
else
{
if (IsFormatAc3(DataFormat))
{
m_fAc3RenderAllocated = TRUE;
}
else
{
m_fPcmRenderAllocated = TRUE;
}
}
*OutStream = PMINIPORTWAVECYCLICSTREAM(stream);
(*OutStream)->AddRef();
*OutDmaChannel = PDMACHANNEL(stream);
(*OutDmaChannel)->AddRef();
*OutServiceGroup = m_ServiceGroup;
(*OutServiceGroup)->AddRef();
// The stream, the DMA channel, and the service group have
// references now for the caller. The caller expects these
// references to be there.
}
// This is our private reference to the stream. The caller has
// its own, so we can release in any case.
//
if (stream)
{
stream->Release();
}
return ntStatus;
} // NewStream
//=============================================================================
STDMETHODIMP_(NTSTATUS)
CMiniportWaveCyclic::NonDelegatingQueryInterface
(
IN REFIID Interface,
OUT PVOID * Object
)
/*++
Routine Description:
QueryInterface
Arguments:
Interface - GUID
Object - interface pointer to be returned.
Return Value:
NT status code.
--*/
{
PAGED_CODE();
ASSERT(Object);
if (IsEqualGUIDAligned(Interface, IID_IUnknown))
{
*Object = PVOID(PUNKNOWN(PMINIPORTWAVECYCLIC(this)));
}
else if (IsEqualGUIDAligned(Interface, IID_IMiniport))
{
*Object = PVOID(PMINIPORT(this));
}
else if (IsEqualGUIDAligned(Interface, IID_IMiniportWaveCyclic))
{
*Object = PVOID(PMINIPORTWAVECYCLIC(this));
}
else
{
*Object = NULL;
}
if (*Object)
{
// We reference the interface for the caller.
PUNKNOWN(*Object)->AddRef();
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
} // NonDelegatingQueryInterface
//=============================================================================
NTSTATUS
CMiniportWaveCyclic::ValidateFormat
(
IN PKSDATAFORMAT pDataFormat
)
/*++
Routine Description:
Validates that the given dataformat is valid. This overwrites BaseWave's
ValidateFormat and includes checks for AC3 format.
Arguments:
pDataFormat - The dataformat for validation.
Return Value:
NT status code.
--*/
{
PAGED_CODE();
DPF_ENTER(("[CMiniportWaveCyclic::ValidateFormat]"));
NTSTATUS ntStatus;
ntStatus = CMiniportWaveCyclicMSVAD::ValidateFormat(pDataFormat);
if (!NT_SUCCESS(ntStatus))
{
PWAVEFORMATEX pwfx;
pwfx = GetWaveFormatEx(pDataFormat);
if (pwfx)
{
if (IS_VALID_WAVEFORMATEX_GUID(&pDataFormat->SubFormat))
{
USHORT wfxID = EXTRACT_WAVEFORMATEX_ID(&pDataFormat->SubFormat);
switch (wfxID)
{
case WAVE_FORMAT_DOLBY_AC3_SPDIF:
{
if
(
(pDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)) &&
(pwfx->cbSize == 0) &&
(pwfx->nChannels <= MAX_CHANNELS_AC3 ) &&
(pwfx->wBitsPerSample >= MIN_BITS_PER_SAMPLE_AC3)&&
(pwfx->wBitsPerSample <= MAX_BITS_PER_SAMPLE_AC3)&&
(pwfx->nSamplesPerSec >= MIN_SAMPLE_RATE_AC3) &&
(pwfx->nSamplesPerSec <= MAX_SAMPLE_RATE_AC3)
)
{
ntStatus = STATUS_SUCCESS;
}
else
{
DPF(D_TERSE, ("Invalid WAVE_FORMAT_DOLBY_AC3_SPDIF format"));
}
break;
}
}
}
else
{
DPF(D_TERSE, ("Invalid pDataFormat->SubFormat!") );
}
}
}
return ntStatus;
} // ValidateFormat
//=============================================================================
// CMiniportWaveStreamCyclicSimple
//=============================================================================
//=============================================================================
CMiniportWaveCyclicStream::~CMiniportWaveCyclicStream
(
void
)
/*++
Routine Description:
Destructor for wavecyclicstream
Arguments:
Return Value:
NT status code.
--*/
{
PAGED_CODE();
DPF_ENTER(("[CMiniportWaveCyclicStream::~CMiniportWaveCyclicStream]"));
if (NULL != m_pMiniportLocal)
{
if (m_fCapture)
{
m_pMiniportLocal->m_fCaptureAllocated = FALSE;
}
else
{
if (m_fFormatAc3)
{
m_pMiniportLocal->m_fAc3RenderAllocated = FALSE;
}
else
{
m_pMiniportLocal->m_fPcmRenderAllocated = FALSE;
}
}
}
} // ~CMiniportWaveCyclicStream
//=============================================================================
NTSTATUS
CMiniportWaveCyclicStream::Init
(
IN PCMiniportWaveCyclic Miniport_,
IN ULONG Pin_,
IN BOOLEAN Capture_,
IN PKSDATAFORMAT DataFormat_
)
/*++
Routine Description:
Initializes the stream object. Allocate a DMA buffer, timer and DPC
Arguments:
Miniport_ -
Pin_ -
Capture_ -
DataFormat -
DmaChannel_ -
Return Value:
NT status code.
--*/
{
PAGED_CODE();
m_pMiniportLocal = Miniport_;
m_fFormatAc3 = IsFormatAc3(DataFormat_);
return
CMiniportWaveCyclicStreamMSVAD::Init
(
Miniport_,
Pin_,
Capture_,
DataFormat_
);
} // Init
//=============================================================================
STDMETHODIMP_(NTSTATUS)
CMiniportWaveCyclicStream::NonDelegatingQueryInterface
(
IN REFIID Interface,
OUT PVOID * Object
)
/*++
Routine Description:
QueryInterface
Arguments:
Interface - GUID
Object - interface pointer to be returned
Return Value:
NT status code.
--*/
{
PAGED_CODE();
ASSERT(Object);
if (IsEqualGUIDAligned(Interface, IID_IUnknown))
{
*Object = PVOID(PUNKNOWN(PMINIPORTWAVECYCLICSTREAM(this)));
}
else if (IsEqualGUIDAligned(Interface, IID_IMiniportWaveCyclicStream))
{
*Object = PVOID(PMINIPORTWAVECYCLICSTREAM(this));
}
else if (IsEqualGUIDAligned(Interface, IID_IDmaChannel))
{
*Object = PVOID(PDMACHANNEL(this));
}
else
{
*Object = NULL;
}
if (*Object)
{
PUNKNOWN(*Object)->AddRef();
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
} // NonDelegatingQueryInterface
#pragma code_seg()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -