mirror of
https://github.com/reactos/reactos.git
synced 2024-09-08 11:50:08 +00:00
200 lines
4.6 KiB
C++
200 lines
4.6 KiB
C++
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS Kernel Streaming
|
|
* FILE: drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp
|
|
* PURPOSE: WaveRTStream helper object
|
|
* PROGRAMMER: Johannes Anderwald
|
|
*/
|
|
|
|
#include "private.hpp"
|
|
|
|
#ifndef YDEBUG
|
|
#define NDEBUG
|
|
#endif
|
|
|
|
#include <debug.h>
|
|
|
|
class CPortWaveRTStreamInit : public IPortWaveRTStreamInit
|
|
{
|
|
public:
|
|
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
|
|
|
STDMETHODIMP_(ULONG) AddRef()
|
|
{
|
|
InterlockedIncrement(&m_Ref);
|
|
return m_Ref;
|
|
}
|
|
STDMETHODIMP_(ULONG) Release()
|
|
{
|
|
InterlockedDecrement(&m_Ref);
|
|
|
|
if (!m_Ref)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return m_Ref;
|
|
}
|
|
IMP_IPortWaveRTStreamInit;
|
|
CPortWaveRTStreamInit(IUnknown *OuterUnknown) {}
|
|
virtual ~CPortWaveRTStreamInit() {}
|
|
|
|
protected:
|
|
LONG m_Ref;
|
|
|
|
};
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CPortWaveRTStreamInit::QueryInterface(
|
|
IN REFIID refiid,
|
|
OUT PVOID* Output)
|
|
{
|
|
|
|
DPRINT("IPortWaveRTStream_fnQueryInterface entered\n");
|
|
|
|
if (IsEqualGUIDAligned(refiid, IID_IPortWaveRTStream) ||
|
|
IsEqualGUIDAligned(refiid, IID_IUnknown))
|
|
{
|
|
*Output = PVOID(PPORTWAVERTSTREAM(this));
|
|
PUNKNOWN(*Output)->AddRef();
|
|
return STATUS_SUCCESS;
|
|
}
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
|
|
PMDL
|
|
NTAPI
|
|
CPortWaveRTStreamInit::AllocatePagesForMdl(
|
|
IN PHYSICAL_ADDRESS HighAddress,
|
|
IN SIZE_T TotalBytes)
|
|
{
|
|
return MmAllocatePagesForMdl(RtlConvertUlongToLargeInteger(0), HighAddress, RtlConvertUlongToLargeInteger(0), TotalBytes);
|
|
}
|
|
|
|
PMDL
|
|
NTAPI
|
|
CPortWaveRTStreamInit::AllocateContiguousPagesForMdl(
|
|
IN PHYSICAL_ADDRESS LowAddress,
|
|
IN PHYSICAL_ADDRESS HighAddress,
|
|
IN SIZE_T TotalBytes)
|
|
{
|
|
PMDL Mdl;
|
|
PVOID Buffer;
|
|
PHYSICAL_ADDRESS Address;
|
|
|
|
Buffer = MmAllocateContiguousMemorySpecifyCache(TotalBytes, LowAddress, HighAddress, RtlConvertUlongToLargeInteger(0), MmNonCached);
|
|
if (!Buffer)
|
|
{
|
|
DPRINT("MmAllocateContiguousMemorySpecifyCache failed\n");
|
|
return NULL;
|
|
}
|
|
|
|
Address = MmGetPhysicalAddress(Buffer);
|
|
|
|
MmFreeContiguousMemorySpecifyCache(Buffer, TotalBytes, MmNonCached);
|
|
|
|
Mdl = MmAllocatePagesForMdl(Address, HighAddress, RtlConvertUlongToLargeInteger(0), TotalBytes);
|
|
if (!Mdl)
|
|
{
|
|
DPRINT("MmAllocatePagesForMdl failed\n");
|
|
return NULL;
|
|
}
|
|
|
|
if (MmGetMdlByteCount(Mdl) < TotalBytes)
|
|
{
|
|
DPRINT("ByteCount %u Required %u\n", MmGetMdlByteCount(Mdl), TotalBytes);
|
|
MmFreePagesFromMdl(Mdl);
|
|
ExFreePool(Mdl);
|
|
return NULL;
|
|
}
|
|
|
|
DPRINT("Result %p\n", Mdl);
|
|
return Mdl;
|
|
}
|
|
|
|
PVOID
|
|
NTAPI
|
|
CPortWaveRTStreamInit::MapAllocatedPages(
|
|
IN PMDL MemoryDescriptorList,
|
|
IN MEMORY_CACHING_TYPE CacheType)
|
|
{
|
|
return MmMapLockedPagesSpecifyCache(MemoryDescriptorList, KernelMode, CacheType, NULL, 0, NormalPagePriority);
|
|
}
|
|
|
|
VOID
|
|
NTAPI
|
|
CPortWaveRTStreamInit::UnmapAllocatedPages(
|
|
IN PVOID BaseAddress,
|
|
IN PMDL MemoryDescriptorList)
|
|
{
|
|
MmUnmapLockedPages(BaseAddress, MemoryDescriptorList);
|
|
}
|
|
|
|
VOID
|
|
NTAPI
|
|
CPortWaveRTStreamInit::FreePagesFromMdl(
|
|
IN PMDL MemoryDescriptorList)
|
|
{
|
|
MmFreePagesFromMdl(MemoryDescriptorList);
|
|
ExFreePool(MemoryDescriptorList);
|
|
}
|
|
|
|
ULONG
|
|
NTAPI
|
|
CPortWaveRTStreamInit::GetPhysicalPagesCount(
|
|
IN PMDL MemoryDescriptorList)
|
|
{
|
|
return ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
|
|
}
|
|
|
|
PHYSICAL_ADDRESS
|
|
NTAPI
|
|
CPortWaveRTStreamInit::GetPhysicalPageAddress(
|
|
IN PPHYSICAL_ADDRESS Address,
|
|
IN PMDL MemoryDescriptorList,
|
|
IN ULONG Index)
|
|
{
|
|
PVOID Buffer;
|
|
ULONG Pages;
|
|
PHYSICAL_ADDRESS Result, Addr;
|
|
|
|
Pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
|
|
if (Pages <= Index)
|
|
{
|
|
DPRINT("OutOfBounds: Pages %u Index %u\n", Pages, Index);
|
|
return RtlConvertUlongToLargeInteger(0);
|
|
}
|
|
|
|
Buffer = (PUCHAR)MmGetSystemAddressForMdlSafe(MemoryDescriptorList, LowPagePriority) + (Index * PAGE_SIZE);
|
|
|
|
Addr = MmGetPhysicalAddress(Buffer);
|
|
Address->QuadPart = Addr.QuadPart;
|
|
Result.QuadPart = (ULONG_PTR)Address;
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
NewPortWaveRTStream(
|
|
PPORTWAVERTSTREAM *OutStream)
|
|
{
|
|
NTSTATUS Status;
|
|
CPortWaveRTStreamInit* This = new(NonPagedPool, TAG_PORTCLASS) CPortWaveRTStreamInit(NULL);
|
|
if (!This)
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
Status = This->QueryInterface(IID_IPortWaveRTStream, (PVOID*)OutStream);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
delete This;
|
|
return Status;
|
|
}
|
|
|
|
*OutStream = (PPORTWAVERTSTREAM)This;
|
|
return Status;
|
|
}
|