winsta: fix spec file
[reactos.git] / reactos / drivers / wdm / audio / backpln / portcls / port_wavertstream.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/port_wavertstream.c
5 * PURPOSE: WaveRTStream helper object
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "private.h"
10
11 typedef struct
12 {
13 IPortWaveRTStreamInitVtbl *lpVtbl;
14 LONG ref;
15
16 }IPortWaveRTStreamImpl;
17
18 /*
19 * @implemented
20 */
21 static
22 NTSTATUS
23 NTAPI
24 IPortWaveRTStreamInit_fnQueryInterface(
25 IPortWaveRTStreamInit * iface,
26 IN REFIID refiid,
27 OUT PVOID* Output)
28 {
29 IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface;
30
31 DPRINT("IPortWaveRTStream_fnQueryInterface entered\n");
32
33 if (IsEqualGUIDAligned(refiid, &IID_IPortWaveRTStream) ||
34 IsEqualGUIDAligned(refiid, &IID_IUnknown))
35 {
36 *Output = &This->lpVtbl;
37 InterlockedIncrement(&This->ref);
38 return STATUS_SUCCESS;
39 }
40 return STATUS_UNSUCCESSFUL;
41 }
42
43 /*
44 * @implemented
45 */
46 static
47 ULONG
48 NTAPI
49 IPortWaveRTStreamInit_fnAddRef(
50 IPortWaveRTStreamInit * iface)
51 {
52 IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface;
53 DPRINT("IPortWaveRTStream_fnAddRef entered\n");
54
55 return InterlockedIncrement(&This->ref);
56 }
57
58 /*
59 * @implemented
60 */
61 static
62 ULONG
63 NTAPI
64 IPortWaveRTStreamInit_fnRelease(
65 IPortWaveRTStreamInit * iface)
66 {
67 IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface;
68
69 InterlockedDecrement(&This->ref);
70
71 DPRINT("IPortWaveRTStream_fnRelease entered %u\n", This->ref);
72
73 if (This->ref == 0)
74 {
75 FreeItem(This, TAG_PORTCLASS);
76 return 0;
77 }
78 /* Return new reference count */
79 return This->ref;
80 }
81
82 /*
83 * @implemented
84 */
85 static
86 PMDL
87 NTAPI
88 IPortWaveRTStreamInit_fnAllocatePagesForMdl(
89 IN IPortWaveRTStreamInit * iface,
90 IN PHYSICAL_ADDRESS HighAddress,
91 IN SIZE_T TotalBytes)
92 {
93 return MmAllocatePagesForMdl(RtlConvertUlongToLargeInteger(0), HighAddress, RtlConvertUlongToLargeInteger(0), TotalBytes);
94 }
95
96 /*
97 * @implemented
98 */
99 static
100 PMDL
101 NTAPI
102 IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl(
103 IN IPortWaveRTStreamInit * iface,
104 IN PHYSICAL_ADDRESS LowAddress,
105 IN PHYSICAL_ADDRESS HighAddress,
106 IN SIZE_T TotalBytes)
107 {
108 PMDL Mdl;
109 PVOID Buffer;
110 PHYSICAL_ADDRESS Address;
111
112 Buffer = MmAllocateContiguousMemorySpecifyCache(TotalBytes, LowAddress, HighAddress, RtlConvertUlongToLargeInteger(0), MmNonCached);
113 if (!Buffer)
114 {
115 DPRINT1("MmAllocateContiguousMemorySpecifyCache failed\n");
116 return NULL;
117 }
118
119 Address = MmGetPhysicalAddress(Buffer);
120
121 MmFreeContiguousMemorySpecifyCache(Buffer, TotalBytes, MmNonCached);
122
123 Mdl = MmAllocatePagesForMdl(Address, HighAddress, RtlConvertUlongToLargeInteger(0), TotalBytes);
124 if (!Mdl)
125 {
126 DPRINT1("MmAllocatePagesForMdl failed\n");
127 return NULL;
128 }
129
130 if (MmGetMdlByteCount(Mdl) < TotalBytes)
131 {
132 DPRINT1("ByteCount %u Required %u\n", MmGetMdlByteCount(Mdl), TotalBytes);
133 MmFreePagesFromMdl(Mdl);
134 ExFreePool(Mdl);
135 return NULL;
136 }
137
138 DPRINT("Result %p\n", Mdl);
139 return Mdl;
140 }
141
142 /*
143 * @implemented
144 */
145 static
146 PVOID
147 NTAPI
148 IPortWaveRTStreamInit_fnMapAllocatedPages(
149 IN IPortWaveRTStreamInit * iface,
150 IN PMDL MemoryDescriptorList,
151 IN MEMORY_CACHING_TYPE CacheType)
152 {
153 return MmMapLockedPagesSpecifyCache(MemoryDescriptorList, KernelMode, CacheType, NULL, 0, NormalPagePriority);
154 }
155
156 /*
157 * @implemented
158 */
159 static
160 VOID
161 NTAPI
162 IPortWaveRTStreamInit_fnUnmapAllocatedPages(
163 IN IPortWaveRTStreamInit * iface,
164 IN PVOID BaseAddress,
165 IN PMDL MemoryDescriptorList)
166 {
167 MmUnmapLockedPages(BaseAddress, MemoryDescriptorList);
168 }
169
170 /*
171 * @implemented
172 */
173 static
174 VOID
175 NTAPI
176 IPortWaveRTStreamInit_fnFreePagesFromMdl(
177 IN IPortWaveRTStreamInit * iface,
178 IN PMDL MemoryDescriptorList)
179 {
180 MmFreePagesFromMdl(MemoryDescriptorList);
181 ExFreePool(MemoryDescriptorList);
182 }
183
184 /*
185 * @implemented
186 */
187 static
188 ULONG
189 NTAPI
190 IPortWaveRTStreamInit_fnGetPhysicalPagesCount(
191 IN IPortWaveRTStreamInit * iface,
192 IN PMDL MemoryDescriptorList)
193 {
194 return ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
195 }
196
197 /*
198 * @implemented
199 */
200 static
201 PHYSICAL_ADDRESS
202 NTAPI
203 IPortWaveRTStreamInit_fnGetPhysicalPageAddress(
204 IN IPortWaveRTStreamInit * iface,
205 IN PPHYSICAL_ADDRESS Address,
206 IN PMDL MemoryDescriptorList,
207 IN ULONG Index)
208 {
209 PVOID Buffer;
210 ULONG Pages;
211 PHYSICAL_ADDRESS Result, Addr;
212
213 Pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
214 if (Pages <= Index)
215 {
216 DPRINT1("OutOfBounds: Pages %u Index %u\n", Pages, Index);
217 return RtlConvertUlongToLargeInteger(0);
218 }
219
220 Buffer = UlongToPtr(PtrToUlong(MmGetSystemAddressForMdl(MemoryDescriptorList)) + Index * PAGE_SIZE);
221
222 Addr = MmGetPhysicalAddress(Buffer);
223 Address->QuadPart = Addr.QuadPart;
224 Result.QuadPart = (PtrToUlong(Address));
225
226 return Result;
227 }
228
229 static IPortWaveRTStreamInitVtbl vt_PortWaveRTStream =
230 {
231 IPortWaveRTStreamInit_fnQueryInterface,
232 IPortWaveRTStreamInit_fnAddRef,
233 IPortWaveRTStreamInit_fnRelease,
234 IPortWaveRTStreamInit_fnAllocatePagesForMdl,
235 IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl,
236 IPortWaveRTStreamInit_fnMapAllocatedPages,
237 IPortWaveRTStreamInit_fnUnmapAllocatedPages,
238 IPortWaveRTStreamInit_fnFreePagesFromMdl,
239 IPortWaveRTStreamInit_fnGetPhysicalPagesCount,
240 IPortWaveRTStreamInit_fnGetPhysicalPageAddress
241 };
242
243 NTSTATUS
244 NewPortWaveRTStream(
245 PPORTWAVERTSTREAM *OutStream)
246 {
247 IPortWaveRTStreamImpl* This = AllocateItem(NonPagedPool, sizeof(IPortWaveRTStreamImpl), TAG_PORTCLASS);
248 if (!This)
249 return STATUS_INSUFFICIENT_RESOURCES;
250
251 This->ref = 1;
252 This->lpVtbl = &vt_PortWaveRTStream;
253
254 *OutStream = (PPORTWAVERTSTREAM)&This->lpVtbl;
255 return STATUS_SUCCESS;
256 }