📄 minwave.cpp
字号:
(*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::UpdateDrmRights
(
void
)
/*++
Routine Description:
Updates the mixed DrmRights. This is done by creating an array of existing
content ids and asking DrmPort to create a new contend id with a mixed
DrmRights structure.
The new DrmRights structure should be enforced, if everything goes well.
Arguments:
Return Value:
NT status code.
--*/
{
PAGED_CODE();
DPF_ENTER(("[CMiniportWaveCyclic::UpdateDrmRights]"));
NTSTATUS ntStatus;
ULONG ulContentIndex = 0;
ULONG ulContentIds[MAX_INPUT_STREAMS];
ULONG ulMixDrmContentId = 0;
BOOL fCreatedContentId = FALSE;
DRMRIGHTS MixDrmRights = {FALSE, 0, FALSE};
// This function only runs if IID_DrmPort is implemented in Wave port.
//
if (!m_pDrmPort)
{
return STATUS_UNSUCCESSFUL;
}
// Create an array of all StreamIds.
//
for (ULONG i = 0; i < MAX_INPUT_STREAMS; i++)
{
if (m_pStream[i])
{
ulContentIds[ulContentIndex] = m_pStream[i]->m_ulContentId;
ulContentIndex++;
}
}
// Create the new contentId.
//
if (ulContentIndex)
{
ntStatus =
m_pDrmPort->CreateContentMixed
(
ulContentIds,
ulContentIndex,
&ulMixDrmContentId
);
if (NT_SUCCESS(ntStatus))
{
fCreatedContentId = TRUE;
ntStatus =
m_pDrmPort->GetContentRights
(
ulMixDrmContentId,
&MixDrmRights
);
}
}
// If successful, destroy the old ContentId and update global rights.
//
if (NT_SUCCESS(ntStatus))
{
m_pDrmPort->DestroyContent(m_ulMixDrmContentId);
m_ulMixDrmContentId = ulMixDrmContentId;
RtlCopyMemory(&m_MixDrmRights, &MixDrmRights, sizeof(m_MixDrmRights));
// At this point the driver should enforce the new DrmRights.
// MSVAD does not have loopback capture caps and does not support
// S/PDIF out, therefore the new MixedRights is ignored.
// MSVAD handles DrmRights per stream basis, and stops writing
// the stream to disk, if CopyProtect = TRUE.
//
}
// Cleanup if failed
//
if (!NT_SUCCESS(ntStatus) && fCreatedContentId)
{
m_pDrmPort->DestroyContent(ulMixDrmContentId);
}
return ntStatus;
} // UpdateDrmRights
//=============================================================================
// 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)
{
// Tell the Miniport that the slot is freed now.
//
if (m_fCapture)
{
m_pMiniportLocal->m_fCaptureAllocated = FALSE;
}
else
{
for (ULONG i = 0; i < m_pMiniportLocal->m_MaxInputStreams; i++)
{
if (this == m_pMiniportLocal->m_pStream[i])
{
m_pMiniportLocal->m_pStream[i] = NULL;
break;
}
}
// Tell the wave miniport to update mixed drm rights.
//
m_pMiniportLocal->UpdateDrmRights();
}
}
} // ~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_ulContentId = 0;
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 if (IsEqualGUIDAligned(Interface, IID_IDrmAudioStream))
{
*Object = (PVOID)(PDRMAUDIOSTREAM)this;
}
else
{
*Object = NULL;
}
if (*Object)
{
PUNKNOWN(*Object)->AddRef();
return STATUS_SUCCESS;
}
return STATUS_INVALID_PARAMETER;
} // NonDelegatingQueryInterface
//=============================================================================
STDMETHODIMP_(NTSTATUS)
CMiniportWaveCyclicStream::SetContentId
(
IN ULONG contentId,
IN PCDRMRIGHTS drmRights
)
/*++
Routine Description:
Sets DRM content Id for this stream. Also updates the Mixed content Id.
Arguments:
contentId - new content id
drmRights - rights for this stream.
Return Value:
NT status code.
--*/
{
PAGED_CODE();
DPF_ENTER(("[CMiniportWaveCyclicStream::SetContentId]"));
NTSTATUS ntStatus;
ULONG ulOldContentId = contentId;
m_ulContentId = contentId;
// Miniport should create a mixed DrmRights.
//
ntStatus = m_pMiniportLocal->UpdateDrmRights();
// Restore the old content Id.
//
if (!NT_SUCCESS(ntStatus))
{
m_ulContentId = ulOldContentId;
}
// MSVAD rights each stream seperately to disk. If the rights for this
// stream indicates that the stream is CopyProtected, stop writing to disk.
//
m_SaveData.Disable(drmRights->CopyProtect);
return ntStatus;
} // SetContentId
#pragma code_seg()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -