ReactOS 0.4.15-dev-5667-ged97270
service_group.cpp
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/service_group.cpp
5 * PURPOSE: ServiceGroup object implementation
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9#include "private.hpp"
10
11#ifndef YDEBUG
12#define NDEBUG
13#endif
14
15#include <debug.h>
16
17VOID
20 IN struct _KDPC *Dpc,
24 );
25
26typedef struct
27{
31
32class CServiceGroup : public CUnknownImpl<IServiceGroup>
33{
34public:
36
38 CServiceGroup(IUnknown * OuterUnknown);
39 virtual ~CServiceGroup() {}
40
41protected:
42
44
49
51};
52
53
54
55//---------------------------------------------------------------
56// IUnknown methods
57//
58
59
63 IN REFIID refiid,
65{
67
68 if (IsEqualGUIDAligned(refiid, IID_IServiceGroup) ||
69 IsEqualGUIDAligned(refiid, IID_IServiceSink) ||
71 {
72 *Output = PVOID(PSERVICEGROUP(this));
73 PUNKNOWN(*Output)->AddRef();
74 return STATUS_SUCCESS;
75 }
76
78 {
79 DPRINT1("CServiceGroup::QueryInterface no interface!!! iface %S\n", GuidString.Buffer);
81 }
82
84}
85//---------------------------------------------------------------
86// IServiceSink methods
87//
88
90{
91 // initialize dpc
93
94 // set highest importance
96
97 // initialize service group list lock
99
100 // initialize service group list
102}
103
104VOID
105NTAPI
106CServiceGroup::RequestService()
107{
109
110 DPRINT("CServiceGroup::RequestService() Dpc at Level %u\n", KeGetCurrentIrql());
111
113 {
115
116 // no due time
117 DueTime.QuadPart = 0LL;
118
119 // delayed service requested
121 }
122 else
123 {
124 // check current irql
126 {
127 //insert dpc to queue
129 }
130 else
131 {
132 // raise irql to dispatch level to make dpc fire immediately
134 // insert dpc to queue
136 // lower irql to old level
138 }
139 }
140}
141
142//---------------------------------------------------------------
143// IServiceGroup methods
144//
145
147NTAPI
148CServiceGroup::AddMember(
149 IN PSERVICESINK pServiceSink)
150{
152 KIRQL OldLevel;
153
154 // sanity check
156
157 // allocate service sink entry
159 if (!Entry)
160 {
161 // out of memory
163 }
164
165 // initialize service sink entry
166 Entry->pServiceSink = pServiceSink;
167 // increment reference count
168 pServiceSink->AddRef();
169
170 // acquire service group list lock
171 KeAcquireSpinLock(&m_Lock, &OldLevel);
172
173 // insert into service sink list
175
176 // release service group list lock
177 KeReleaseSpinLock(&m_Lock, OldLevel);
178
179 return STATUS_SUCCESS;
180}
181
182VOID
183NTAPI
184CServiceGroup::RemoveMember(
185 IN PSERVICESINK pServiceSink)
186{
187 PLIST_ENTRY CurEntry;
189 KIRQL OldLevel;
190
191 // sanity check
193
194 // acquire service group list lock
195 KeAcquireSpinLock(&m_Lock, &OldLevel);
196
197 // grab first entry
198 CurEntry = m_ServiceSinkHead.Flink;
199
200 // loop list until the passed entry is found
201 while (CurEntry != &m_ServiceSinkHead)
202 {
203 // grab entry
205
206 // check if it matches the passed entry
207 if (Entry->pServiceSink == pServiceSink)
208 {
209 // remove entry from list
211
212 // release service sink reference
213 pServiceSink->Release();
214
215 // free service sink entry
217
218 // leave loop
219 break;
220 }
221 // move to next entry
222 CurEntry = CurEntry->Flink;
223 }
224
225 // release service group list lock
226 KeReleaseSpinLock(&m_Lock, OldLevel);
227
228}
229
230VOID
231NTAPI
233 IN struct _KDPC *Dpc,
237 )
238{
239 PLIST_ENTRY CurEntry;
242
243 // acquire service group list lock
245
246 // grab first entry
247 CurEntry = This->m_ServiceSinkHead.Flink;
248
249 // loop the list and call the attached service sink/group
250 while (CurEntry != &This->m_ServiceSinkHead)
251 {
252 //grab current entry
254
255 // call service sink/group
256 Entry->pServiceSink->RequestService();
257
258 // move to next entry
259 CurEntry = CurEntry->Flink;
260 }
261
262 // release service group list lock
264}
265
266VOID
267NTAPI
268CServiceGroup::SupportDelayedService()
269{
271
272 // initialize the timer
274
275 // use the timer to perform service requests
277}
278
279VOID
280NTAPI
281CServiceGroup::RequestDelayedService(
282 IN ULONGLONG ullDelay)
283{
285
286 // sanity check
289
290 DueTime.QuadPart = ullDelay;
291
292 // set the timer
294}
295
296VOID
297NTAPI
298CServiceGroup::CancelDelayedService()
299{
302
303 // cancel the timer
305}
306
308NTAPI
310 OUT PSERVICEGROUP* OutServiceGroup,
311 IN PUNKNOWN OuterUnknown OPTIONAL)
312{
315
316 DPRINT("PcNewServiceGroup entered\n");
317
318 //FIXME support aggregation
319 PC_ASSERT(OuterUnknown == NULL);
320
321 // allocate a service group object
322 This = new(NonPagedPool, TAG_PORTCLASS)CServiceGroup(OuterUnknown);
323
324 if (!This)
325 {
326 // out of memory
328 }
329
330 // request IServiceSink interface
331 Status = This->QueryInterface(IID_IServiceSink, (PVOID*)OutServiceGroup);
332
333 if (!NT_SUCCESS(Status))
334 {
335 // failed to acquire service sink interface
336 delete This;
337 return Status;
338 }
339
340 // done
341 return Status;
342}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define STDMETHODIMP
Definition: basetyps.h:43
const GUID IID_IUnknown
virtual ~CServiceGroup()
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
friend VOID NTAPI IServiceGroupDpc(IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
KSPIN_LOCK m_Lock
LIST_ENTRY m_ServiceSinkHead
CServiceGroup(IUnknown *OuterUnknown)
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
VOID NTAPI KeSetImportanceDpc(IN PKDPC Dpc, IN KDPC_IMPORTANCE Importance)
Definition: dpc.c:958
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
ULONG AddRef()
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
static PWSTR GuidString
Definition: apphelp.c:93
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
IServiceSink * PSERVICESINK
Definition: portcls.h:569
IServiceGroup * PSERVICEGROUP
Definition: portcls.h:614
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
#define PC_ASSERT_IRQL(x)
Definition: private.hpp:30
#define TAG_PORTCLASS
Definition: private.hpp:24
#define PC_ASSERT(exp)
Definition: private.hpp:26
#define REFIID
Definition: guiddef.h:118
@ Output
Definition: arc.h:85
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
VOID NTAPI IServiceGroupDpc(IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
NTSTATUS NTAPI PcNewServiceGroup(OUT PSERVICEGROUP *OutServiceGroup, IN PUNKNOWN OuterUnknown OPTIONAL)
struct GROUP_ENTRY * PGROUP_ENTRY
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
base of all file and directory entries
Definition: entries.h:83
Entry(ENTRY_TYPE etype)
Definition: entries.cpp:35
LIST_ENTRY Entry
IN PSERVICESINK pServiceSink
Definition: ketypes.h:687
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
#define LL
Definition: tui.h:150
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_In_ WDFTIMER _In_ LONGLONG DueTime
Definition: wdftimer.h:190
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
@ HighImportance
Definition: ketypes.h:683
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:676
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:677