ReactOS  0.4.15-dev-1018-g0695ecb
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 #ifndef YDEBUG
15 #define NDEBUG
16 #endif
17 
18 #include <debug.h>
19 
20 typedef struct
21 {
25 
26 
28 NTAPI
31  IN PIRP Irp)
32 {
33  DPRINT("PortClsCreate called\n");
34 
36 }
37 
38 
40 NTAPI
43  IN PIRP Irp)
44 {
46  PPCLASS_DEVICE_EXTENSION DeviceExt;
47  PIO_STACK_LOCATION IoStack;
49  IResourceList* resource_list = NULL;
50  //ULONG Index;
51  //PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor, UnPartialDescriptor;
52 
55 
56 
57  DPRINT("PortClsPnp called %u\n", IoStack->MinorFunction);
58 
59  //PC_ASSERT(DeviceExt);
60 
61  switch (IoStack->MinorFunction)
62  {
64  DPRINT("IRP_MN_START_DEVICE\n");
65 
66  // Create the resource list
68  &resource_list,
69  NULL,
70  PagedPool,
71  IoStack->Parameters.StartDevice.AllocatedResourcesTranslated,
72  IoStack->Parameters.StartDevice.AllocatedResources);
73  if (!NT_SUCCESS(Status))
74  {
75  DPRINT("PcNewResourceList failed [0x%8x]\n", Status);
76  Irp->IoStatus.Status = Status;
78  return Status;
79  }
80 
81  // forward irp to lower device object
83 
84  if (!NT_SUCCESS(Status))
85  {
86  // lower device object failed to start
87  resource_list->Release();
88  // complete the request
90  // return result
91  return Status;
92  }
93 
94  // sanity check
95  //PC_ASSERT(DeviceExt->StartDevice);
96  // Call the StartDevice routine
97  DPRINT("Calling StartDevice at 0x%8p\n", DeviceExt->StartDevice);
98  Status = DeviceExt->StartDevice(DeviceObject, Irp, resource_list);
99  if (!NT_SUCCESS(Status))
100  {
101  DPRINT("StartDevice returned a failure code [0x%8x]\n", Status);
102  Irp->IoStatus.Status = Status;
104  return Status;
105  }
106 
107  // Assign the resource list to our extension
108  DeviceExt->resources = resource_list;
109 
110  // store device power state
111  DeviceExt->DevicePowerState = PowerDeviceD0;
113 
114  // notify power manager of current state
117 
118  Irp->IoStatus.Status = STATUS_SUCCESS;
120  return Status;
121 
123  // Clean up
124  DPRINT("IRP_MN_REMOVE_DEVICE\n");
125 
126  // sanity check
127  PC_ASSERT(DeviceExt);
128 
129  // FIXME more cleanup */
130  if (DeviceExt->resources)
131  {
132  // free resource list */
133  DeviceExt->resources->Release();
134 
135  // set to null
136  DeviceExt->resources = NULL;
137  }
138 
139  // Forward request
141 
143 
145  DPRINT("IRP_MN_QUERY_INTERFACE\n");
149  DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n");
153  DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
157  DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
160  case IRP_MN_READ_CONFIG:
161  DPRINT("IRP_MN_READ_CONFIG\n");
164  }
165 
166  DPRINT("unhandled function %u\n", IoStack->MinorFunction);
167  Status = Irp->IoStatus.Status;
169  return Status;
170 }
171 
172 VOID
173 CALLBACK
178  IN PVOID Context,
180 {
183 
184  if (NT_SUCCESS(IoStatus->Status))
185  {
186  // forward request to lower device object
187  Status = PcForwardIrpSynchronous(PwrContext->DeviceObject, PwrContext->Irp);
188  }
189  else
190  {
191  // failed
192  Status = IoStatus->Status;
193  }
194 
195  // start next power irp
196  PoStartNextPowerIrp(PwrContext->Irp);
197 
198  // complete request
199  PwrContext->Irp->IoStatus.Status = Status;
200  IoCompleteRequest(PwrContext->Irp, IO_NO_INCREMENT);
201 
202  // free context
203  FreeItem(PwrContext, TAG_PORTCLASS);
204 }
205 
206 
207 NTSTATUS
208 NTAPI
211  IN PIRP Irp)
212 {
213  PIO_STACK_LOCATION IoStack;
214  PPCLASS_DEVICE_EXTENSION DeviceExtension;
215  PQUERY_POWER_CONTEXT PwrContext;
218 
219  DPRINT("PortClsPower called\n");
220 
221  // get currrent stack location
223 
224  // get device extension
226 
228  {
229  // forward unknown requests down the stack and forget
232  return PoCallDriver(DeviceExtension->PrevDeviceObject, Irp);
233  }
234 
235  // get current request type
236  if (IoStack->Parameters.Power.Type == DevicePowerState)
237  {
238  // request for device power state
239  if (DeviceExtension->DevicePowerState == IoStack->Parameters.Power.State.DeviceState)
240  {
241  // nothing has changed
242  if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
243  {
244  // only forward query requests; we can forget about them
247  return PoCallDriver(DeviceExtension->PrevDeviceObject, Irp);
248  }
249 
250  // start next power irp
252 
253  // complete request
254  Irp->IoStatus.Status = Status;
256 
257  // done
258  return Status;
259  }
260 
261  if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
262  {
263  // check if there is a registered adapter power management
264  if (DeviceExtension->AdapterPowerManagement)
265  {
266  // it is query if the change can be changed
267  PowerState = IoStack->Parameters.Power.State;
268  Status = DeviceExtension->AdapterPowerManagement->QueryPowerChangeState(PowerState);
269 
270  if (!NT_SUCCESS(Status))
271  {
272  // fail the IRP if the adapter power manager failed
274  Irp->IoStatus.Status = Status;
276  return Status;
277  }
278  }
279 
280  // only forward query requests
283  return PoCallDriver(DeviceExtension->PrevDeviceObject, Irp);
284  }
285  else
286  {
287  // set power state
288  PowerState = IoStack->Parameters.Power.State;
290 
291  // check if there is a registered adapter power management
292  if (DeviceExtension->AdapterPowerManagement)
293  {
294  // notify of a power change state
295  DeviceExtension->AdapterPowerManagement->PowerChangeState(PowerState);
296  }
297 
298  // FIXME call all registered IPowerNotify interfaces via ISubdevice interface
299 
300  // store new power state
301  DeviceExtension->DevicePowerState = IoStack->Parameters.Power.State.DeviceState;
302 
303  // complete request
304  Irp->IoStatus.Status = Status;
306 
307  // done
308  return Status;
309  }
310  }
311  else
312  {
313  // sanity check
314  PC_ASSERT(IoStack->Parameters.Power.Type == SystemPowerState);
315 
316  if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
317  {
318  // mark irp as pending
320 
321  // allocate power completion context
323 
324  if (!PwrContext)
325  {
326  // no memory
328 
329  // complete and forget
330  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
332 
333  // done
334  return STATUS_PENDING;
335  }
336 
337  // setup power context
338  PwrContext->Irp = Irp;
339  PwrContext->DeviceObject = DeviceObject;
340 
341  // pass the irp down
342  PowerState = IoStack->Parameters.Power.State;
344 
345  // check for success
346  if (!NT_SUCCESS(Status))
347  {
348  // failed
349  Irp->IoStatus.Status = Status;
351 
352  // done
353  return STATUS_PENDING;
354  }
355 
356  // done
357  return STATUS_PENDING;
358  }
359  else
360  {
361  // set power request
362  DeviceExtension->SystemPowerState = IoStack->Parameters.Power.State.SystemState;
363 
364  // only forward query requests
367  return PoCallDriver(DeviceExtension->PrevDeviceObject, Irp);
368  }
369  }
370 }
371 
372 NTSTATUS
373 NTAPI
376  IN PIRP Irp)
377 {
378  DPRINT("PortClsSysControl called\n");
379 
380  // TODO
381 
382  Irp->IoStatus.Status = STATUS_SUCCESS;
383  Irp->IoStatus.Information = 0;
385 
386  return STATUS_SUCCESS;
387 }
388 
389 NTSTATUS
390 NTAPI
393  IN PIRP Irp)
394 {
395  PPCLASS_DEVICE_EXTENSION DeviceExtension;
396  DPRINT("PortClsShutdown called\n");
397 
398  // get device extension
400 
401  if (DeviceExtension->AdapterPowerManagement)
402  {
403  // release adapter power management
404  DPRINT("Power %u\n", DeviceExtension->AdapterPowerManagement->Release());
405  }
406 
407  Irp->IoStatus.Status = STATUS_SUCCESS;
408  Irp->IoStatus.Information = 0;
410 
411  return STATUS_SUCCESS;
412 }
413 
414 NTSTATUS
415 NTAPI
418  IN PIRP Irp)
419 {
420  PIO_STACK_LOCATION IoStack;
421 
423 
424  DPRINT("PcDispatchIrp called - handling IRP in PortCls MajorFunction %x MinorFunction %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
425 
426  switch ( IoStack->MajorFunction )
427  {
428  // PortCls
429  case IRP_MJ_CREATE :
430  return PortClsCreate(DeviceObject, Irp);
431 
432  case IRP_MJ_PNP :
433  return PortClsPnp(DeviceObject, Irp);
434 
435  case IRP_MJ_POWER :
436  return PortClsPower(DeviceObject, Irp);
437 
439  return KsDispatchIrp(DeviceObject, Irp);
440 
441  case IRP_MJ_CLOSE:
442  return KsDispatchIrp(DeviceObject, Irp);
443 
444  case IRP_MJ_SYSTEM_CONTROL :
446 
447  case IRP_MJ_SHUTDOWN:
449 
450  default:
451  DPRINT("Unhandled function %x\n", IoStack->MajorFunction);
452  break;
453  };
454 
455  // If we reach here, we just complete the IRP
456  Irp->IoStatus.Status = STATUS_SUCCESS;
457  Irp->IoStatus.Information = 0;
459 
460  return STATUS_SUCCESS;
461 }
462 
463 
464 NTSTATUS
465 NTAPI
468  IN PIRP Irp,
470 {
471 #if 0
473  PC_ASSERT(Irp);
475 #endif
476 
477  Irp->IoStatus.Status = Status;
479 
480  return Status;
481 }
482 
483 NTSTATUS
484 NTAPI
487  IN PIRP Irp,
488  IN PVOID Context)
489 {
490  if (Irp->PendingReturned != FALSE)
491  {
493  }
495 }
496 
497 #undef IoSetCompletionRoutine
498 #define IoSetCompletionRoutine(_Irp, \
499  _CompletionRoutine, \
500  _Context, \
501  _InvokeOnSuccess, \
502  _InvokeOnError, \
503  _InvokeOnCancel) \
504 { \
505  PIO_STACK_LOCATION _IrpSp; \
506  _IrpSp = IoGetNextIrpStackLocation(_Irp); \
507  _IrpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)(_CompletionRoutine); \
508  _IrpSp->Context = (_Context); \
509  _IrpSp->Control = 0; \
510  if (_InvokeOnSuccess) _IrpSp->Control = SL_INVOKE_ON_SUCCESS; \
511  if (_InvokeOnError) _IrpSp->Control |= SL_INVOKE_ON_ERROR; \
512  if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \
513 }
514 
515 
516 
517 NTSTATUS
518 NTAPI
521  IN PIRP Irp)
522 {
523  KEVENT Event;
524  PPCLASS_DEVICE_EXTENSION DeviceExt;
526 
528 
530 
531  // initialize the notification event
533 
534  // are there enough irp stack locations
535  if (Irp->CurrentLocation < Irp->StackCount + 1)
536  {
538  }
539 
541 
542  // now call the driver
543  Status = IoCallDriver(DeviceExt->PrevDeviceObject, Irp);
544  // did the request complete yet
545  if (Status == STATUS_PENDING)
546  {
547  // not yet, lets wait a bit
549  Status = Irp->IoStatus.Status;
550  }
551  return Status;
552 }
PDEVICE_OBJECT PrevDeviceObject
Definition: private.hpp:403
#define IN
Definition: typedefs.h:39
PDEVICE_OBJECT DeviceObject
Definition: irp.cpp:23
_In_ UCHAR _In_ POWER_STATE PowerState
Definition: pofuncs.h:42
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
KSDDKAPI NTSTATUS NTAPI KsDispatchIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:2063
#define IRP_MN_QUERY_POWER
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2659
#define IRP_MJ_SHUTDOWN
struct PCLASS_DEVICE_EXTENSION * PPCLASS_DEVICE_EXTENSION
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
#define TAG_PORTCLASS
Definition: private.hpp:24
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
LONG NTSTATUS
Definition: precomp.h:26
#define CALLBACK
Definition: compat.h:35
NTSTATUS NTAPI PcForwardIrpSynchronous(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:519
struct QUERY_POWER_CONTEXT * PQUERY_POWER_CONTEXT
IResourceList * resources
Definition: private.hpp:410
IO_STATUS_BLOCK IoStatus
PCPFNSTARTDEVICE StartDevice
Definition: private.hpp:404
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PC_ASSERT(exp)
Definition: private.hpp:26
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2864
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
DEVICE_POWER_STATE DevicePowerState
Definition: private.hpp:415
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI PortClsShutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:391
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:439
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS NTAPI PortClsPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:41
void DPRINT(...)
Definition: polytest.cpp:61
#define IRP_MN_READ_CONFIG
if(!(yy_init))
Definition: macro.lex.yy.c:714
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:174
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
PDEVICE_OBJECT PhysicalDeviceObject
Definition: private.hpp:402
NTSTATUS NTAPI PortClsSysControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:374
#define IRP_MN_START_DEVICE
DEVICE_POWER_STATE DeviceState
Definition: ntpoapi.h:58
#define IRP_MN_QUERY_INTERFACE
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
Status
Definition: gdiplustypes.h:24
#define IRP_MN_SET_POWER
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
_In_ UCHAR MinorFunction
Definition: pofuncs.h:42
#define IRP_MJ_SYSTEM_CONTROL
NTSTATUS NTAPI PortClsCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:29
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
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:310
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
IAdapterPowerManagement * AdapterPowerManagement
Definition: private.hpp:406
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:737
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
NTSTATUS NTAPI PcCompleteIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN NTSTATUS Status)
Definition: irp.cpp:466
SYSTEM_POWER_STATE SystemPowerState
Definition: private.hpp:416
NTSTATUS NTAPI CompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: irp.cpp:485
#define IO_NO_INCREMENT
Definition: iotypes.h:570
POWER_STATE NTAPI PoSetPowerState(IN PDEVICE_OBJECT DeviceObject, IN POWER_STATE_TYPE Type, IN POWER_STATE State)
Definition: power.c:708
NTSTATUS NTAPI PcDispatchIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:416
NTSTATUS NTAPI PoRequestPowerIrp(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PREQUEST_POWER_COMPLETE CompletionFunction, IN PVOID Context, OUT PIRP *pIrp OPTIONAL)
Definition: power.c:639
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
NTSTATUS NTAPI PortClsPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:209
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52