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