ReactOS  0.4.12-dev-934-g9a4676f
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  if (IoStack->MinorFunction != IRP_MN_SET_POWER && IoStack->MinorFunction != IRP_MN_QUERY_POWER)
225  {
226  // just forward the request
228 
229  // start next power irp
231 
232  // complete request
233  Irp->IoStatus.Status = Status;
235 
236  // done
237  return Status;
238  }
239 
240 
241  // get device extension
243 
244  // get current request type
245  if (IoStack->Parameters.Power.Type == DevicePowerState)
246  {
247  // request for device power state
248  if (DeviceExtension->DevicePowerState == IoStack->Parameters.Power.State.DeviceState)
249  {
250  // nothing has changed
251  if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
252  {
253  // only forward query requests
255  }
256 
257  // start next power irp
259 
260  // complete request
261  Irp->IoStatus.Status = Status;
263 
264  // done
265  return Status;
266  }
267 
268  if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
269  {
270  // check if there is a registered adapter power management
271  if (DeviceExtension->AdapterPowerManagement)
272  {
273  // it is query if the change can be changed
274  PowerState = IoStack->Parameters.Power.State;
275  Status = DeviceExtension->AdapterPowerManagement->QueryPowerChangeState(PowerState);
276 
277  // sanity check
279  }
280 
281  // only forward query requests
283 
284  // start next power irp
286 
287  // complete request
288  Irp->IoStatus.Status = Status;
290 
291  // done
292  return Status;
293  }
294  else
295  {
296  // set power state
297  PowerState = IoStack->Parameters.Power.State;
299 
300  // check if there is a registered adapter power management
301  if (DeviceExtension->AdapterPowerManagement)
302  {
303  // notify of a power change state
304  DeviceExtension->AdapterPowerManagement->PowerChangeState(PowerState);
305  }
306 
307  // FIXME call all registered IPowerNotify interfaces via ISubdevice interface
308 
309  // store new power state
310  DeviceExtension->DevicePowerState = IoStack->Parameters.Power.State.DeviceState;
311 
312  // complete request
313  Irp->IoStatus.Status = Status;
315 
316  // done
317  return Status;
318  }
319  }
320  else
321  {
322  // sanity check
323  PC_ASSERT(IoStack->Parameters.Power.Type == SystemPowerState);
324 
325  if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
326  {
327  // mark irp as pending
329 
330  // allocate power completion context
332 
333  if (!PwrContext)
334  {
335  // no memory
337 
338  // complete and forget
339  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
341 
342  // done
343  return Status;
344  }
345 
346  // setup power context
347  PwrContext->Irp = Irp;
348  PwrContext->DeviceObject = DeviceObject;
349 
350  // pass the irp down
351  PowerState = IoStack->Parameters.Power.State;
353 
354  // check for success
355  if (!NT_SUCCESS(Status))
356  {
357  // failed
358  Irp->IoStatus.Status = Status;
360 
361  // done
362  return Status;
363  }
364 
365  // done
366  return STATUS_PENDING;
367  }
368  else
369  {
370  // set power request
371  DeviceExtension->SystemPowerState = IoStack->Parameters.Power.State.SystemState;
372 
373  // only forward query requests
375 
376  // start next power irp
378 
379  // complete request
380  Irp->IoStatus.Status = Status;
382 
383  // done
384  return Status;
385  }
386  }
387 }
388 
389 NTSTATUS
390 NTAPI
393  IN PIRP Irp)
394 {
395  DPRINT("PortClsSysControl called\n");
396 
397  // TODO
398 
399  Irp->IoStatus.Status = STATUS_SUCCESS;
400  Irp->IoStatus.Information = 0;
402 
403  return STATUS_SUCCESS;
404 }
405 
406 NTSTATUS
407 NTAPI
410  IN PIRP Irp)
411 {
412  PPCLASS_DEVICE_EXTENSION DeviceExtension;
413  DPRINT("PortClsShutdown called\n");
414 
415  // get device extension
417 
418  if (DeviceExtension->AdapterPowerManagement)
419  {
420  // release adapter power management
421  DPRINT("Power %u\n", DeviceExtension->AdapterPowerManagement->Release());
422  }
423 
424  Irp->IoStatus.Status = STATUS_SUCCESS;
425  Irp->IoStatus.Information = 0;
427 
428  return STATUS_SUCCESS;
429 }
430 
431 NTSTATUS
432 NTAPI
435  IN PIRP Irp)
436 {
437  PIO_STACK_LOCATION IoStack;
438 
440 
441  DPRINT("PcDispatchIrp called - handling IRP in PortCls MajorFunction %x MinorFunction %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
442 
443  switch ( IoStack->MajorFunction )
444  {
445  // PortCls
446  case IRP_MJ_CREATE :
447  return PortClsCreate(DeviceObject, Irp);
448 
449  case IRP_MJ_PNP :
450  return PortClsPnp(DeviceObject, Irp);
451 
452  case IRP_MJ_POWER :
453  return PortClsPower(DeviceObject, Irp);
454 
456  return KsDispatchIrp(DeviceObject, Irp);
457 
458  case IRP_MJ_CLOSE:
459  return KsDispatchIrp(DeviceObject, Irp);
460 
461  case IRP_MJ_SYSTEM_CONTROL :
463 
464  case IRP_MJ_SHUTDOWN:
466 
467  default:
468  DPRINT("Unhandled function %x\n", IoStack->MajorFunction);
469  break;
470  };
471 
472  // If we reach here, we just complete the IRP
473  Irp->IoStatus.Status = STATUS_SUCCESS;
474  Irp->IoStatus.Information = 0;
476 
477  return STATUS_SUCCESS;
478 }
479 
480 
481 NTSTATUS
482 NTAPI
485  IN PIRP Irp,
487 {
488 #if 0
490  PC_ASSERT(Irp);
492 #endif
493 
494  Irp->IoStatus.Status = Status;
496 
497  return Status;
498 }
499 
500 NTSTATUS
501 NTAPI
504  IN PIRP Irp,
505  IN PVOID Context)
506 {
507  if (Irp->PendingReturned != FALSE)
508  {
510  }
512 }
513 
514 #undef IoSetCompletionRoutine
515 #define IoSetCompletionRoutine(_Irp, \
516  _CompletionRoutine, \
517  _Context, \
518  _InvokeOnSuccess, \
519  _InvokeOnError, \
520  _InvokeOnCancel) \
521 { \
522  PIO_STACK_LOCATION _IrpSp; \
523  _IrpSp = IoGetNextIrpStackLocation(_Irp); \
524  _IrpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)(_CompletionRoutine); \
525  _IrpSp->Context = (_Context); \
526  _IrpSp->Control = 0; \
527  if (_InvokeOnSuccess) _IrpSp->Control = SL_INVOKE_ON_SUCCESS; \
528  if (_InvokeOnError) _IrpSp->Control |= SL_INVOKE_ON_ERROR; \
529  if (_InvokeOnCancel) _IrpSp->Control |= SL_INVOKE_ON_CANCEL; \
530 }
531 
532 
533 
534 NTSTATUS
535 NTAPI
538  IN PIRP Irp)
539 {
540  KEVENT Event;
541  PPCLASS_DEVICE_EXTENSION DeviceExt;
543 
545 
547 
548  // initialize the notification event
550 
551  // are there enough irp stack locations
552  if (Irp->CurrentLocation < Irp->StackCount + 1)
553  {
555  }
556 
558 
559  // now call the driver
560  Status = IoCallDriver(DeviceExt->PrevDeviceObject, Irp);
561  // did the request complete yet
562  if (Status == STATUS_PENDING)
563  {
564  // not yet, lets wait a bit
566  Status = Irp->IoStatus.Status;
567  }
568  return Status;
569 }
PDEVICE_OBJECT PrevDeviceObject
Definition: private.hpp:396
#define IN
Definition: typedefs.h:38
PDEVICE_OBJECT DeviceObject
Definition: irp.cpp:23
#define TRUE
Definition: types.h:120
_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
#define PC_ASSERT(exp)
Definition: usbehci.h:17
KSDDKAPI NTSTATUS NTAPI KsDispatchIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:2051
#define IRP_MN_QUERY_POWER
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
#define IRP_MJ_SHUTDOWN
struct PCLASS_DEVICE_EXTENSION * PPCLASS_DEVICE_EXTENSION
_In_ PIRP Irp
Definition: csq.h:116
#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:27
NTSTATUS NTAPI PcForwardIrpSynchronous(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:536
struct QUERY_POWER_CONTEXT * PQUERY_POWER_CONTEXT
IResourceList * resources
Definition: private.hpp:403
PCPFNSTARTDEVICE StartDevice
Definition: private.hpp:397
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 IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
DEVICE_POWER_STATE DevicePowerState
Definition: private.hpp:408
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
NTSTATUS NTAPI PortClsShutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:408
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
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:395
NTSTATUS NTAPI PortClsSysControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:391
#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
#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
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI PortClsCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:29
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
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:2745
IAdapterPowerManagement * AdapterPowerManagement
Definition: private.hpp:399
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:619
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
NTSTATUS NTAPI PcCompleteIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN NTSTATUS Status)
Definition: irp.cpp:483
SYSTEM_POWER_STATE SystemPowerState
Definition: private.hpp:409
NTSTATUS NTAPI CompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: irp.cpp:502
#define IO_NO_INCREMENT
Definition: iotypes.h:565
POWER_STATE NTAPI PoSetPowerState(IN PDEVICE_OBJECT DeviceObject, IN POWER_STATE_TYPE Type, IN POWER_STATE State)
Definition: power.c:590
NTSTATUS NTAPI PcDispatchIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:433
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:521
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2725
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