ReactOS 0.4.16-dev-334-g4d9f67c
irp.cpp
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS
4 * FILE: drivers/wdm/audio/backpln/portcls/irp.cpp
5 * PURPOSE: Port Class driver / IRP Handling
6 * PROGRAMMER: Andrew Greenwood
7 * Johannes Anderwald
8 * HISTORY:
9 * 27 Jan 07 Created
10 */
11
12#include "private.hpp"
13
14#define NDEBUG
15#include <debug.h>
16
17typedef struct
18{
22
27 IN PIRP Irp)
28{
29 DPRINT("PortClsCreate called\n");
30
32}
33
38 IN PIRP Irp)
39{
42 PIO_STACK_LOCATION IoStack;
44 IResourceList* resource_list = NULL;
45 //ULONG Index;
46 //PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor, UnPartialDescriptor;
47
48 DeviceExt = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
50
51 DPRINT("PortClsPnp called %u\n", IoStack->MinorFunction);
52
53 //PC_ASSERT(DeviceExt);
54
55 switch (IoStack->MinorFunction)
56 {
58 DPRINT("IRP_MN_START_DEVICE\n");
59
60 // Create the resource list
62 &resource_list,
63 NULL,
65 IoStack->Parameters.StartDevice.AllocatedResourcesTranslated,
66 IoStack->Parameters.StartDevice.AllocatedResources);
67 if (!NT_SUCCESS(Status))
68 {
69 DPRINT("PcNewResourceList failed [0x%8x]\n", Status);
70 Irp->IoStatus.Status = Status;
72 return Status;
73 }
74
75 // forward irp to lower device object
77
78 if (!NT_SUCCESS(Status))
79 {
80 // lower device object failed to start
81 resource_list->Release();
82 // complete the request
84 // return result
85 return Status;
86 }
87
88 // sanity check
89 //PC_ASSERT(DeviceExt->StartDevice);
90 // Call the StartDevice routine
91 DPRINT("Calling StartDevice at 0x%8p\n", DeviceExt->StartDevice);
92 Status = DeviceExt->StartDevice(DeviceObject, Irp, resource_list);
93 if (!NT_SUCCESS(Status))
94 {
95 DPRINT("StartDevice returned a failure code [0x%8x]\n", Status);
96 Irp->IoStatus.Status = Status;
98 return Status;
99 }
100
101 // Assign the resource list to our extension
102 DeviceExt->resources = resource_list;
103
104 // store device power state
105 DeviceExt->DevicePowerState = PowerDeviceD0;
107
108 // notify power manager of current state
109 PowerState.DeviceState = DeviceExt->DevicePowerState;
111
112 Irp->IoStatus.Status = STATUS_SUCCESS;
114 return Status;
115
117 // Clean up
118 DPRINT("IRP_MN_REMOVE_DEVICE\n");
119
120 // sanity check
121 PC_ASSERT(DeviceExt);
122
123 // FIXME more cleanup */
124 if (DeviceExt->resources)
125 {
126 // free resource list */
127 DeviceExt->resources->Release();
128
129 // set to null
130 DeviceExt->resources = NULL;
131 }
132
133 // Forward request
135
137
139 DPRINT("IRP_MN_QUERY_INTERFACE\n");
143 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
147 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
151 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
155 DPRINT("IRP_MN_READ_CONFIG\n");
158 }
159
160 DPRINT("unhandled function %u\n", IoStack->MinorFunction);
161 Status = Irp->IoStatus.Status;
163 return Status;
164}
165
166VOID
174{
177
178 if (NT_SUCCESS(IoStatus->Status))
179 {
180 // forward request to lower device object
181 Status = PcForwardIrpSynchronous(PwrContext->DeviceObject, PwrContext->Irp);
182 }
183 else
184 {
185 // failed
186 Status = IoStatus->Status;
187 }
188
189 // start next power irp
190 PoStartNextPowerIrp(PwrContext->Irp);
191
192 // complete request
193 PwrContext->Irp->IoStatus.Status = Status;
195
196 // free context
197 FreeItem(PwrContext, TAG_PORTCLASS);
198}
199
201NTAPI
204 IN PIRP Irp)
205{
206 PIO_STACK_LOCATION IoStack;
207 PPCLASS_DEVICE_EXTENSION DeviceExtension;
208 PQUERY_POWER_CONTEXT PwrContext;
211
212 DPRINT("PortClsPower called\n");
213
214 // get currrent stack location
216
217 // get device extension
218 DeviceExtension = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
219
221 {
222 // forward unknown requests down the stack and forget
225 return PoCallDriver(DeviceExtension->PrevDeviceObject, Irp);
226 }
227
228 // get current request type
229 if (IoStack->Parameters.Power.Type == DevicePowerState)
230 {
231 // request for device power state
232 if (DeviceExtension->DevicePowerState == IoStack->Parameters.Power.State.DeviceState)
233 {
234 // nothing has changed
235 if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
236 {
237 // only forward query requests; we can forget about them
240 return PoCallDriver(DeviceExtension->PrevDeviceObject, Irp);
241 }
242
243 // start next power irp
245
246 // complete request
247 Irp->IoStatus.Status = Status;
249
250 // done
251 return Status;
252 }
253
254 if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
255 {
256 // check if there is a registered adapter power management
257 if (DeviceExtension->AdapterPowerManagement)
258 {
259 // it is query if the change can be changed
260 PowerState = IoStack->Parameters.Power.State;
261 Status = DeviceExtension->AdapterPowerManagement->QueryPowerChangeState(PowerState);
262
263 if (!NT_SUCCESS(Status))
264 {
265 // fail the IRP if the adapter power manager failed
267 Irp->IoStatus.Status = Status;
269 return Status;
270 }
271 }
272
273 // only forward query requests
276 return PoCallDriver(DeviceExtension->PrevDeviceObject, Irp);
277 }
278 else
279 {
280 // set power state
281 PowerState = IoStack->Parameters.Power.State;
283
284 // check if there is a registered adapter power management
285 if (DeviceExtension->AdapterPowerManagement)
286 {
287 // notify of a power change state
288 DeviceExtension->AdapterPowerManagement->PowerChangeState(PowerState);
289 }
290
291 // FIXME call all registered IPowerNotify interfaces via ISubdevice interface
292
293 // store new power state
294 DeviceExtension->DevicePowerState = IoStack->Parameters.Power.State.DeviceState;
295
296 // complete request
297 Irp->IoStatus.Status = Status;
299
300 // done
301 return Status;
302 }
303 }
304 else
305 {
306 // sanity check
307 PC_ASSERT(IoStack->Parameters.Power.Type == SystemPowerState);
308
309 if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
310 {
311 // mark irp as pending
313
314 // allocate power completion context
316
317 if (!PwrContext)
318 {
319 // no memory
321
322 // complete and forget
323 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
325
326 // done
327 return STATUS_PENDING;
328 }
329
330 // setup power context
331 PwrContext->Irp = Irp;
332 PwrContext->DeviceObject = DeviceObject;
333
334 // pass the irp down
335 PowerState = IoStack->Parameters.Power.State;
337
338 // check for success
339 if (!NT_SUCCESS(Status))
340 {
341 // failed
342 Irp->IoStatus.Status = Status;
344
345 // done
346 return STATUS_PENDING;
347 }
348
349 // done
350 return STATUS_PENDING;
351 }
352 else
353 {
354 // set power request
355 DeviceExtension->SystemPowerState = IoStack->Parameters.Power.State.SystemState;
356
357 // only forward query requests
360 return PoCallDriver(DeviceExtension->PrevDeviceObject, Irp);
361 }
362 }
363}
364
366NTAPI
369 IN PIRP Irp)
370{
371 DPRINT("PortClsSysControl called\n");
372
373 // TODO
374
375 Irp->IoStatus.Status = STATUS_SUCCESS;
376 Irp->IoStatus.Information = 0;
378
379 return STATUS_SUCCESS;
380}
381
383NTAPI
386 IN PIRP Irp)
387{
388 PPCLASS_DEVICE_EXTENSION DeviceExtension;
389 DPRINT("PortClsShutdown called\n");
390
391 // get device extension
392 DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
393
394 if (DeviceExtension->AdapterPowerManagement)
395 {
396 // release adapter power management
397 DPRINT("Power %u\n", DeviceExtension->AdapterPowerManagement->Release());
398 }
399
400 Irp->IoStatus.Status = STATUS_SUCCESS;
401 Irp->IoStatus.Information = 0;
403
404 return STATUS_SUCCESS;
405}
406
408NTAPI
411 IN PIRP Irp)
412{
413 PIO_STACK_LOCATION IoStack;
414
416
417 DPRINT("PcDispatchIrp called - handling IRP in PortCls MajorFunction %x MinorFunction %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
418
419 switch ( IoStack->MajorFunction )
420 {
421 // PortCls
422 case IRP_MJ_CREATE :
424
425 case IRP_MJ_PNP :
426 return PortClsPnp(DeviceObject, Irp);
427
428 case IRP_MJ_POWER :
430
433
434 case IRP_MJ_CLOSE:
436
439
440 case IRP_MJ_SHUTDOWN:
442
443 default:
444 DPRINT("Unhandled function %x\n", IoStack->MajorFunction);
445 break;
446 };
447
448 // If we reach here, we just complete the IRP
449 Irp->IoStatus.Status = STATUS_SUCCESS;
450 Irp->IoStatus.Information = 0;
452
453 return STATUS_SUCCESS;
454}
455
457NTAPI
460 IN PIRP Irp,
462{
463#if 0
465 PC_ASSERT(Irp);
467#endif
468
469 Irp->IoStatus.Status = Status;
471
472 return Status;
473}
474
476NTAPI
479 IN PIRP Irp,
481{
482 if (Irp->PendingReturned != FALSE)
483 {
485 }
487}
488
489#undef IoSetCompletionRoutine
490#define IoSetCompletionRoutine(_Irp, \
491 _CompletionRoutine, \
492 _Context, \
493 _InvokeOnSuccess, \
494 _InvokeOnError, \
495 _InvokeOnCancel) \
496{ \
497 PIO_STACK_LOCATION _IrpSp; \
498 _IrpSp = IoGetNextIrpStackLocation(_Irp); \
499 _IrpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)(_CompletionRoutine); \
500 _IrpSp->Context = (_Context); \
501 _IrpSp->Control = 0; \
502 if (_InvokeOnSuccess) _IrpSp->Control = SL_INVOKE_ON_SUCCESS; \
503 if (_InvokeOnError) _IrpSp->Control |= SL_INVOKE_ON_ERROR; \
504 if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \
505}
506
508NTAPI
511 IN PIRP Irp)
512{
514 PPCLASS_DEVICE_EXTENSION DeviceExt;
516
518
519 DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
520
521 // initialize the notification event
523
524 // are there enough irp stack locations
525 if (Irp->CurrentLocation < Irp->StackCount + 1)
526 {
528 }
529
531
532 // now call the driver
534 // did the request complete yet
535 if (Status == STATUS_PENDING)
536 {
537 // not yet, lets wait a bit
539 Status = Irp->IoStatus.Status;
540 }
541 return Status;
542}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define CALLBACK
Definition: compat.h:35
KSDDKAPI NTSTATUS NTAPI KsDispatchIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:2084
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:25
IoMarkIrpPending(Irp)
struct QUERY_POWER_CONTEXT * PQUERY_POWER_CONTEXT
NTSTATUS NTAPI PortClsPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:36
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
NTSTATUS NTAPI PcDispatchIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:409
NTSTATUS NTAPI PcForwardIrpSynchronous(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:509
NTSTATUS NTAPI PortClsShutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:384
NTSTATUS NTAPI PortClsPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:202
NTSTATUS NTAPI PortClsCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:25
NTSTATUS NTAPI PcCompleteIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN NTSTATUS Status)
Definition: irp.cpp:458
VOID CALLBACK PwrCompletionFunction(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus)
Definition: irp.cpp:168
NTSTATUS NTAPI PortClsSysControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:367
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
if(dx< 0)
Definition: linetemp.h:194
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
POWER_STATE NTAPI PoSetPowerState(IN PDEVICE_OBJECT DeviceObject, IN POWER_STATE_TYPE Type, IN POWER_STATE State)
Definition: power.c:729
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:758
NTSTATUS NTAPI PoRequestPowerIrp(_In_ PDEVICE_OBJECT DeviceObject, _In_ UCHAR MinorFunction, _In_ POWER_STATE PowerState, _In_opt_ PREQUEST_POWER_COMPLETE CompletionFunction, _In_opt_ __drv_aliasesMem PVOID Context, _Outptr_opt_ PIRP *pIrp)
Definition: power.c:659
@ PowerSystemWorking
Definition: ntpoapi.h:36
@ DevicePowerState
Definition: ntpoapi.h:63
@ PowerDeviceD0
Definition: ntpoapi.h:49
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
struct PCLASS_DEVICE_EXTENSION * PPCLASS_DEVICE_EXTENSION
#define TAG_PORTCLASS
Definition: private.hpp:24
#define PC_ASSERT(exp)
Definition: private.hpp:26
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
PORTCLASSAPI NTSTATUS NTAPI PcNewResourceList(OUT PRESOURCELIST *OutResourceList, IN PUNKNOWN OuterUnknown OPTIONAL, IN POOL_TYPE PoolType, IN PCM_RESOURCE_LIST TranslatedResourceList, IN PCM_RESOURCE_LIST UntranslatedResourceList)
Definition: resource.cpp:295
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
IResourceList * resources
Definition: private.hpp:410
PDEVICE_OBJECT PhysicalDeviceObject
Definition: private.hpp:402
PDEVICE_OBJECT PrevDeviceObject
Definition: private.hpp:403
IAdapterPowerManagement * AdapterPowerManagement
Definition: private.hpp:406
SYSTEM_POWER_STATE SystemPowerState
Definition: private.hpp:416
PCPFNSTARTDEVICE StartDevice
Definition: private.hpp:404
DEVICE_POWER_STATE DevicePowerState
Definition: private.hpp:415
PDEVICE_OBJECT DeviceObject
Definition: irp.cpp:20
union _IO_STACK_LOCATION::@1581 Parameters
struct _IO_STACK_LOCATION::@3980::@4016 Power
struct _IO_STACK_LOCATION::@3980::@4017 StartDevice
IO_STATUS_BLOCK IoStatus
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ WDF_DEVICE_POWER_STATE PowerState
Definition: wdfdevice.h:3034
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1699
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_QUERY_INTERFACE
#define IRP_MN_START_DEVICE
#define IRP_MN_READ_CONFIG
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MJ_SYSTEM_CONTROL
#define IRP_MN_SET_POWER
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_POWER
_In_ SYSTEM_POWER_STATE SystemPowerState
Definition: iotypes.h:7519
#define IRP_MN_QUERY_POWER
@ Executive
Definition: ketypes.h:415
unsigned char UCHAR
Definition: xmlstorage.h:181