1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT: ReactOS Kernel Streaming
4c2c66affSColin Finck * FILE: drivers/wdm/audio/backpln/portcls/port_wavertstream.cpp
5c2c66affSColin Finck * PURPOSE: WaveRTStream helper object
6c2c66affSColin Finck * PROGRAMMER: Johannes Anderwald
7c2c66affSColin Finck */
8c2c66affSColin Finck
9c2c66affSColin Finck #include "private.hpp"
10c2c66affSColin Finck
11c2c66affSColin Finck #define NDEBUG
12c2c66affSColin Finck #include <debug.h>
13c2c66affSColin Finck
14*6e97b431SVictor Perevertkin class CPortWaveRTStreamInit : public CUnknownImpl<IPortWaveRTStreamInit>
15c2c66affSColin Finck {
16c2c66affSColin Finck public:
17c2c66affSColin Finck STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
18c2c66affSColin Finck
19c2c66affSColin Finck IMP_IPortWaveRTStreamInit;
CPortWaveRTStreamInit(IUnknown * OuterUnknown)20c2c66affSColin Finck CPortWaveRTStreamInit(IUnknown *OuterUnknown) {}
~CPortWaveRTStreamInit()21c2c66affSColin Finck virtual ~CPortWaveRTStreamInit() {}
22c2c66affSColin Finck
23c2c66affSColin Finck };
24c2c66affSColin Finck
25c2c66affSColin Finck NTSTATUS
26c2c66affSColin Finck NTAPI
QueryInterface(IN REFIID refiid,OUT PVOID * Output)27c2c66affSColin Finck CPortWaveRTStreamInit::QueryInterface(
28c2c66affSColin Finck IN REFIID refiid,
29c2c66affSColin Finck OUT PVOID* Output)
30c2c66affSColin Finck {
31c2c66affSColin Finck
32c2c66affSColin Finck DPRINT("IPortWaveRTStream_fnQueryInterface entered\n");
33c2c66affSColin Finck
34c2c66affSColin Finck if (IsEqualGUIDAligned(refiid, IID_IPortWaveRTStream) ||
35c2c66affSColin Finck IsEqualGUIDAligned(refiid, IID_IUnknown))
36c2c66affSColin Finck {
37c2c66affSColin Finck *Output = PVOID(PPORTWAVERTSTREAM(this));
38c2c66affSColin Finck PUNKNOWN(*Output)->AddRef();
39c2c66affSColin Finck return STATUS_SUCCESS;
40c2c66affSColin Finck }
41c2c66affSColin Finck return STATUS_UNSUCCESSFUL;
42c2c66affSColin Finck }
43c2c66affSColin Finck
44c2c66affSColin Finck PMDL
45c2c66affSColin Finck NTAPI
AllocatePagesForMdl(IN PHYSICAL_ADDRESS HighAddress,IN SIZE_T TotalBytes)46c2c66affSColin Finck CPortWaveRTStreamInit::AllocatePagesForMdl(
47c2c66affSColin Finck IN PHYSICAL_ADDRESS HighAddress,
48c2c66affSColin Finck IN SIZE_T TotalBytes)
49c2c66affSColin Finck {
50c2c66affSColin Finck return MmAllocatePagesForMdl(RtlConvertUlongToLargeInteger(0), HighAddress, RtlConvertUlongToLargeInteger(0), TotalBytes);
51c2c66affSColin Finck }
52c2c66affSColin Finck
53c2c66affSColin Finck PMDL
54c2c66affSColin Finck NTAPI
AllocateContiguousPagesForMdl(IN PHYSICAL_ADDRESS LowAddress,IN PHYSICAL_ADDRESS HighAddress,IN SIZE_T TotalBytes)55c2c66affSColin Finck CPortWaveRTStreamInit::AllocateContiguousPagesForMdl(
56c2c66affSColin Finck IN PHYSICAL_ADDRESS LowAddress,
57c2c66affSColin Finck IN PHYSICAL_ADDRESS HighAddress,
58c2c66affSColin Finck IN SIZE_T TotalBytes)
59c2c66affSColin Finck {
60c2c66affSColin Finck PMDL Mdl;
61c2c66affSColin Finck PVOID Buffer;
62c2c66affSColin Finck PHYSICAL_ADDRESS Address;
63c2c66affSColin Finck
64c2c66affSColin Finck Buffer = MmAllocateContiguousMemorySpecifyCache(TotalBytes, LowAddress, HighAddress, RtlConvertUlongToLargeInteger(0), MmNonCached);
65c2c66affSColin Finck if (!Buffer)
66c2c66affSColin Finck {
67c2c66affSColin Finck DPRINT("MmAllocateContiguousMemorySpecifyCache failed\n");
68c2c66affSColin Finck return NULL;
69c2c66affSColin Finck }
70c2c66affSColin Finck
71c2c66affSColin Finck Address = MmGetPhysicalAddress(Buffer);
72c2c66affSColin Finck
73c2c66affSColin Finck MmFreeContiguousMemorySpecifyCache(Buffer, TotalBytes, MmNonCached);
74c2c66affSColin Finck
75c2c66affSColin Finck Mdl = MmAllocatePagesForMdl(Address, HighAddress, RtlConvertUlongToLargeInteger(0), TotalBytes);
76c2c66affSColin Finck if (!Mdl)
77c2c66affSColin Finck {
78c2c66affSColin Finck DPRINT("MmAllocatePagesForMdl failed\n");
79c2c66affSColin Finck return NULL;
80c2c66affSColin Finck }
81c2c66affSColin Finck
82c2c66affSColin Finck if (MmGetMdlByteCount(Mdl) < TotalBytes)
83c2c66affSColin Finck {
84c2c66affSColin Finck DPRINT("ByteCount %u Required %u\n", MmGetMdlByteCount(Mdl), TotalBytes);
85c2c66affSColin Finck MmFreePagesFromMdl(Mdl);
86c2c66affSColin Finck ExFreePool(Mdl);
87c2c66affSColin Finck return NULL;
88c2c66affSColin Finck }
89c2c66affSColin Finck
90c2c66affSColin Finck DPRINT("Result %p\n", Mdl);
91c2c66affSColin Finck return Mdl;
92c2c66affSColin Finck }
93c2c66affSColin Finck
94c2c66affSColin Finck PVOID
95c2c66affSColin Finck NTAPI
MapAllocatedPages(IN PMDL MemoryDescriptorList,IN MEMORY_CACHING_TYPE CacheType)96c2c66affSColin Finck CPortWaveRTStreamInit::MapAllocatedPages(
97c2c66affSColin Finck IN PMDL MemoryDescriptorList,
98c2c66affSColin Finck IN MEMORY_CACHING_TYPE CacheType)
99c2c66affSColin Finck {
100c2c66affSColin Finck return MmMapLockedPagesSpecifyCache(MemoryDescriptorList, KernelMode, CacheType, NULL, 0, NormalPagePriority);
101c2c66affSColin Finck }
102c2c66affSColin Finck
103c2c66affSColin Finck VOID
104c2c66affSColin Finck NTAPI
UnmapAllocatedPages(IN PVOID BaseAddress,IN PMDL MemoryDescriptorList)105c2c66affSColin Finck CPortWaveRTStreamInit::UnmapAllocatedPages(
106c2c66affSColin Finck IN PVOID BaseAddress,
107c2c66affSColin Finck IN PMDL MemoryDescriptorList)
108c2c66affSColin Finck {
109c2c66affSColin Finck MmUnmapLockedPages(BaseAddress, MemoryDescriptorList);
110c2c66affSColin Finck }
111c2c66affSColin Finck
112c2c66affSColin Finck VOID
113c2c66affSColin Finck NTAPI
FreePagesFromMdl(IN PMDL MemoryDescriptorList)114c2c66affSColin Finck CPortWaveRTStreamInit::FreePagesFromMdl(
115c2c66affSColin Finck IN PMDL MemoryDescriptorList)
116c2c66affSColin Finck {
117c2c66affSColin Finck MmFreePagesFromMdl(MemoryDescriptorList);
118c2c66affSColin Finck ExFreePool(MemoryDescriptorList);
119c2c66affSColin Finck }
120c2c66affSColin Finck
121c2c66affSColin Finck ULONG
122c2c66affSColin Finck NTAPI
GetPhysicalPagesCount(IN PMDL MemoryDescriptorList)123c2c66affSColin Finck CPortWaveRTStreamInit::GetPhysicalPagesCount(
124c2c66affSColin Finck IN PMDL MemoryDescriptorList)
125c2c66affSColin Finck {
126c2c66affSColin Finck return ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
127c2c66affSColin Finck }
128c2c66affSColin Finck
129c2c66affSColin Finck PHYSICAL_ADDRESS
130c2c66affSColin Finck NTAPI
GetPhysicalPageAddress(IN PPHYSICAL_ADDRESS Address,IN PMDL MemoryDescriptorList,IN ULONG Index)131c2c66affSColin Finck CPortWaveRTStreamInit::GetPhysicalPageAddress(
132c2c66affSColin Finck IN PPHYSICAL_ADDRESS Address,
133c2c66affSColin Finck IN PMDL MemoryDescriptorList,
134c2c66affSColin Finck IN ULONG Index)
135c2c66affSColin Finck {
136c2c66affSColin Finck PVOID Buffer;
137c2c66affSColin Finck ULONG Pages;
138c2c66affSColin Finck PHYSICAL_ADDRESS Result, Addr;
139c2c66affSColin Finck
140c2c66affSColin Finck Pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
141c2c66affSColin Finck if (Pages <= Index)
142c2c66affSColin Finck {
143c2c66affSColin Finck DPRINT("OutOfBounds: Pages %u Index %u\n", Pages, Index);
144c2c66affSColin Finck return RtlConvertUlongToLargeInteger(0);
145c2c66affSColin Finck }
146c2c66affSColin Finck
147c2c66affSColin Finck Buffer = (PUCHAR)MmGetSystemAddressForMdlSafe(MemoryDescriptorList, LowPagePriority) + (Index * PAGE_SIZE);
148c2c66affSColin Finck
149c2c66affSColin Finck Addr = MmGetPhysicalAddress(Buffer);
150c2c66affSColin Finck Address->QuadPart = Addr.QuadPart;
151c2c66affSColin Finck Result.QuadPart = (ULONG_PTR)Address;
152c2c66affSColin Finck
153c2c66affSColin Finck return Result;
154c2c66affSColin Finck }
155c2c66affSColin Finck
156c2c66affSColin Finck NTSTATUS
NewPortWaveRTStream(PPORTWAVERTSTREAM * OutStream)157c2c66affSColin Finck NewPortWaveRTStream(
158c2c66affSColin Finck PPORTWAVERTSTREAM *OutStream)
159c2c66affSColin Finck {
160c2c66affSColin Finck NTSTATUS Status;
161c2c66affSColin Finck CPortWaveRTStreamInit* This = new(NonPagedPool, TAG_PORTCLASS) CPortWaveRTStreamInit(NULL);
162c2c66affSColin Finck if (!This)
163c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
164c2c66affSColin Finck
165c2c66affSColin Finck Status = This->QueryInterface(IID_IPortWaveRTStream, (PVOID*)OutStream);
166c2c66affSColin Finck
167c2c66affSColin Finck if (!NT_SUCCESS(Status))
168c2c66affSColin Finck {
169c2c66affSColin Finck delete This;
170c2c66affSColin Finck return Status;
171c2c66affSColin Finck }
172c2c66affSColin Finck
173c2c66affSColin Finck *OutStream = (PPORTWAVERTSTREAM)This;
174c2c66affSColin Finck return Status;
175c2c66affSColin Finck }
176