ReactOS  0.4.14-dev-293-g2b39b42
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 
17 VOID
18 NTAPI
20  IN struct _KDPC *Dpc,
24  );
25 
26 typedef struct
27 {
31 
32 class CServiceGroup : public IServiceGroup
33 {
34 public:
36 
38  {
40  return m_Ref;
41  }
43  {
45 
46  if (!m_Ref)
47  {
48  delete this;
49  return 0;
50  }
51  return m_Ref;
52  }
53 
55  CServiceGroup(IUnknown * OuterUnknown);
56  virtual ~CServiceGroup() {}
57 
58 protected:
59 
61 
66 
68 
70 
71 };
72 
73 
74 
75 //---------------------------------------------------------------
76 // IUnknown methods
77 //
78 
79 
81 NTAPI
83  IN REFIID refiid,
84  OUT PVOID* Output)
85 {
87 
88  if (IsEqualGUIDAligned(refiid, IID_IServiceGroup) ||
89  IsEqualGUIDAligned(refiid, IID_IServiceSink) ||
91  {
92  *Output = PVOID(PSERVICEGROUP(this));
93  PUNKNOWN(*Output)->AddRef();
94  return STATUS_SUCCESS;
95  }
96 
98  {
99  DPRINT1("CServiceGroup::QueryInterface no interface!!! iface %S\n", GuidString.Buffer);
101  }
102 
103  return STATUS_UNSUCCESSFUL;
104 }
105 //---------------------------------------------------------------
106 // IServiceSink methods
107 //
108 
110 {
111  // initialize dpc
113 
114  // set highest importance
116 
117  // initialize service group list lock
119 
120  // initialize service group list
122 }
123 
124 VOID
125 NTAPI
126 CServiceGroup::RequestService()
127 {
128  KIRQL OldIrql;
129 
130  DPRINT("CServiceGroup::RequestService() Dpc at Level %u\n", KeGetCurrentIrql());
131 
132  if (m_TimerInitialized)
133  {
135 
136  // no due time
137  DueTime.QuadPart = 0LL;
138 
139  // delayed service requested
141  }
142  else
143  {
144  // check current irql
146  {
147  //insert dpc to queue
149  }
150  else
151  {
152  // raise irql to dispatch level to make dpc fire immediately
154  // insert dpc to queue
156  // lower irql to old level
158  }
159  }
160 }
161 
162 //---------------------------------------------------------------
163 // IServiceGroup methods
164 //
165 
166 NTSTATUS
167 NTAPI
168 CServiceGroup::AddMember(
169  IN PSERVICESINK pServiceSink)
170 {
172  KIRQL OldLevel;
173 
174  // sanity check
176 
177  // allocate service sink entry
179  if (!Entry)
180  {
181  // out of memory
183  }
184 
185  // initialize service sink entry
186  Entry->pServiceSink = pServiceSink;
187  // increment reference count
188  pServiceSink->AddRef();
189 
190  // acquire service group list lock
191  KeAcquireSpinLock(&m_Lock, &OldLevel);
192 
193  // insert into service sink list
195 
196  // release service group list lock
197  KeReleaseSpinLock(&m_Lock, OldLevel);
198 
199  return STATUS_SUCCESS;
200 }
201 
202 VOID
203 NTAPI
204 CServiceGroup::RemoveMember(
205  IN PSERVICESINK pServiceSink)
206 {
207  PLIST_ENTRY CurEntry;
209  KIRQL OldLevel;
210 
211  // sanity check
213 
214  // acquire service group list lock
215  KeAcquireSpinLock(&m_Lock, &OldLevel);
216 
217  // grab first entry
218  CurEntry = m_ServiceSinkHead.Flink;
219 
220  // loop list until the passed entry is found
221  while (CurEntry != &m_ServiceSinkHead)
222  {
223  // grab entry
225 
226  // check if it matches the passed entry
227  if (Entry->pServiceSink == pServiceSink)
228  {
229  // remove entry from list
231 
232  // release service sink reference
233  pServiceSink->Release();
234 
235  // free service sink entry
237 
238  // leave loop
239  break;
240  }
241  // move to next entry
242  CurEntry = CurEntry->Flink;
243  }
244 
245  // release service group list lock
246  KeReleaseSpinLock(&m_Lock, OldLevel);
247 
248 }
249 
250 VOID
251 NTAPI
253  IN struct _KDPC *Dpc,
257  )
258 {
259  PLIST_ENTRY CurEntry;
262 
263  // acquire service group list lock
265 
266  // grab first entry
267  CurEntry = This->m_ServiceSinkHead.Flink;
268 
269  // loop the list and call the attached service sink/group
270  while (CurEntry != &This->m_ServiceSinkHead)
271  {
272  //grab current entry
274 
275  // call service sink/group
276  Entry->pServiceSink->RequestService();
277 
278  // move to next entry
279  CurEntry = CurEntry->Flink;
280  }
281 
282  // release service group list lock
284 }
285 
286 VOID
287 NTAPI
288 CServiceGroup::SupportDelayedService()
289 {
291 
292  // initialize the timer
294 
295  // use the timer to perform service requests
297 }
298 
299 VOID
300 NTAPI
301 CServiceGroup::RequestDelayedService(
302  IN ULONGLONG ullDelay)
303 {
305 
306  // sanity check
309 
310  DueTime.QuadPart = ullDelay;
311 
312  // set the timer
314 }
315 
316 VOID
317 NTAPI
318 CServiceGroup::CancelDelayedService()
319 {
322 
323  // cancel the timer
325 }
326 
327 NTSTATUS
328 NTAPI
330  OUT PSERVICEGROUP* OutServiceGroup,
331  IN PUNKNOWN OuterUnknown OPTIONAL)
332 {
335 
336  DPRINT("PcNewServiceGroup entered\n");
337 
338  //FIXME support aggregation
339  PC_ASSERT(OuterUnknown == NULL);
340 
341  // allocate a service group object
342  This = new(NonPagedPool, TAG_PORTCLASS)CServiceGroup(OuterUnknown);
343 
344  if (!This)
345  {
346  // out of memory
348  }
349 
350  // request IServiceSink interface
351  Status = This->QueryInterface(IID_IServiceSink, (PVOID*)OutServiceGroup);
352 
353  if (!NT_SUCCESS(Status))
354  {
355  // failed to acquire service sink interface
356  delete This;
357  return Status;
358  }
359 
360  // done
361  return Status;
362 }
STDMETHODIMP_(ULONG) Release()
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
IServiceGroup * PSERVICEGROUP
Definition: portcls.h:614
static PWSTR GuidString
Definition: apphelp.c:91
#define IN
Definition: typedefs.h:38
VOID NTAPI IServiceGroupDpc(IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define LL
Definition: tui.h:85
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
LIST_ENTRY Entry
#define PC_ASSERT(exp)
Definition: usbehci.h:17
struct _Entry Entry
Definition: kefuncs.h:640
_In_ BOOLEAN Release
Definition: classpnp.h:929
_In_ LARGE_INTEGER DueTime
Definition: kefuncs.h:524
IUnknown * PUNKNOWN
Definition: com_apitest.h:45
#define TAG_PORTCLASS
Definition: private.hpp:24
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:724
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeSetImportanceDpc(IN PKDPC Dpc, IN KDPC_IMPORTANCE Importance)
Definition: dpc.c:957
IServiceSink * PSERVICESINK
Definition: portcls.h:569
LIST_ENTRY m_ServiceSinkHead
#define InsertTailList(ListHead, Entry)
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
Entry(ENTRY_TYPE etype)
Definition: entries.cpp:35
#define STDMETHODIMP
Definition: basetyps.h:43
CServiceGroup(IUnknown *OuterUnknown)
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
IN PSERVICESINK pServiceSink
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
KSPIN_LOCK m_Lock
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
const GUID IID_IUnknown
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
ULONG AddRef()
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: ketypes.h:687
Definition: arc.h:85
Definition: typedefs.h:117
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define InterlockedIncrement
Definition: armddk.h:53
STDMETHODIMP_(ULONG) AddRef()
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:39
struct GROUP_ENTRY * PGROUP_ENTRY
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI PcNewServiceGroup(OUT PSERVICEGROUP *OutServiceGroup, IN PUNKNOWN OuterUnknown OPTIONAL)
virtual ~CServiceGroup()
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
STDMETHODIMP QueryInterface(REFIID InterfaceId, PVOID *Interface)
return STATUS_SUCCESS
Definition: btrfs.c:2966
base of all file and directory entries
Definition: entries.h:82
#define PC_ASSERT_IRQL(x)
Definition: private.hpp:30
LONGLONG QuadPart
Definition: typedefs.h:112
friend VOID NTAPI IServiceGroupDpc(IN struct _KDPC *Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675