ReactOS  0.4.15-dev-3428-g0609db5
fxpkgfdokm.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxPkgFdo.cpp
8 
9 Abstract:
10 
11  This module implements the pnp/power package for the driver
12  framework.
13 
14 Author:
15 
16 
17 
18 Environment:
19 
20  Kernel mode only
21 
22 Revision History:
23 
24 
25 
26 --*/
27 
28 #include "../pnppriv.hpp"
29 
30 #include <initguid.h>
31 #include <wdmguid.h>
32 
33 
34 #if defined(EVENT_TRACING)
35 // Tracing support
36 extern "C" {
37 #include "FxPkgFdoKm.tmh"
38 }
39 #endif
40 
45  )
46 
47 /*++
48 
49 Routine Description:
50 
51  This method is invoked in response to a Pnp FilterResourceRequirements IRP.
52 
53 Arguments:
54 
55  Device - a pointer to the FxDevice
56 
57  Irp - a pointer to the FxIrp
58 
59 Returns:
60 
61  NTSTATUS
62 
63 --*/
64 
65 {
66  PIO_RESOURCE_REQUIREMENTS_LIST pWdmRequirementsList;
70  WDFIORESREQLIST reqlist;
71 
73  "Entering FilterResourceRequirements handler");
74 
76 
77  pWdmRequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST) Irp->GetInformation();
78 
80 
82  pWdmRequirementsList,
84 
85  if (pIoResReqList != NULL) {
86  status = pIoResReqList->Commit(NULL, (PWDFOBJECT) &reqlist);
87 
88  // Commit should never fail because we own all object state
91 
94 
96  pNewWdmList = pIoResReqList->CreateWdmList();
97 
98  if (pNewWdmList != NULL) {
99  //
100  // List could be missing previously
101  //
102  if (pWdmRequirementsList != NULL) {
103  //
104  // Propagate BusNumber to our new list.
105  //
106  pNewWdmList->BusNumber = pWdmRequirementsList->BusNumber;
107 
108  MxMemory::MxFreePool(pWdmRequirementsList);
109  }
110 
111  Irp->SetInformation((ULONG_PTR) pNewWdmList);
112  }
113  else {
115  }
116  }
117 
118  //
119  // No matter what, free the resource requirements list object. If
120  // we need another one when adding resources, another one will be
121  // allocated.
122  //
125  }
126  }
127  else {
128  //
129  // No filtering on the way down, set status to STATUS_SUCCESS so we
130  // send the irp down the stack.
131  //
133  }
134 
135  if (NT_SUCCESS(status)) {
137  }
138 
139  //
140  // If we do not handle the IRP on the way down and the PDO does not handle
141  // the IRP, we can have a status of STATUS_NOT_SUPPORTED. We still want to
142  // process the irp in this state.
143  //
145  NTSTATUS filterStatus;
146 
147  //
148  // Give the Framework objects a pass at the list.
149  //
151  (PIO_RESOURCE_REQUIREMENTS_LIST*)(&Irp->GetIrp()->IoStatus.Information)
152  );
153 
154  if (!NT_SUCCESS(filterStatus)) {
155  status = filterStatus;
156  }
158  //
159  // Now give the driver a shot at it.
160  //
161  pWdmRequirementsList = (PIO_RESOURCE_REQUIREMENTS_LIST)
162  Irp->GetInformation();
163 
165  GetDriverGlobals(), pWdmRequirementsList, FxResourceAllAccessAllowed);
166 
167  if (pIoResReqList != NULL) {
168  status = pIoResReqList->Commit(NULL, (PWDFOBJECT) &reqlist);
170 
171  //
172  // Since we absolutely control the lifetime of pIoResReqList, this
173  // should never fail
174  //
176 
178  m_Device->GetHandle(), reqlist);
179 
180  //
181  // It is possible the child driver modified the resource list,
182  // and if so we need to update the requirements list.
183  //
185  pNewWdmList = pIoResReqList->CreateWdmList();
186 
187  if (pNewWdmList != NULL) {
188  //
189  // List could be missing previously
190  //
191  if (pWdmRequirementsList != NULL) {
192  //
193  // Propagate BusNumber to our new list.
194  //
195  pNewWdmList->BusNumber = pWdmRequirementsList->BusNumber;
196 
197  ExFreePool(pWdmRequirementsList);
198  }
199 
200  Irp->SetInformation((ULONG_PTR) pNewWdmList);
201  }
202  else {
204  }
205  }
206 
209  }
210  else {
212  }
213  }
214  }
215 
217 
219  "Exiting FilterResourceRequirements handler, %!STATUS!",
220  status);
221 
222  return status;
223 }
224 
226 NTSTATUS
229  __inout MdIrp Irp,
231  )
232 {
236 
237  ASSERTMSG("Not implemented for KMDF\n", FALSE);
238 
239  return STATUS_NOT_IMPLEMENTED;
240 }
241 
243 NTSTATUS
245  __inout FxIrp *Irp
246  )
247 
248 /*++
249 
250 Routine Description:
251 
252  This method is invoked in response to a Pnp QueryCapabilities IRP.
253 
254 Arguments:
255 
256  Device - a pointer to the FxDevice
257 
258  Irp - a pointer to the FxIrp
259 
260 Returns:
261 
262  NTSTATUS
263 
264 --*/
265 
266 {
268 
270 
272 
273  //
274  // Now that the IRP has returned to us, we modify what the bus driver
275  // set up.
276  //
277  if (NT_SUCCESS(status)) {
279  }
280 
282 
283  return status;
284 }
285 
287 NTSTATUS
290  __inout MdIrp Irp,
292  )
293 {
297 
298  ASSERTMSG("Not implemented for KMDF\n", FALSE);
299 
300  return STATUS_NOT_IMPLEMENTED;
301 }
302 
304 NTSTATUS
307  __inout FxIrp *Irp
308  )
309 
310 /*++
311 
312 Routine Description:
313 
314  This method is invoked in response to a Pnp QueryPnpDeviceState IRP.
315 
316 Arguments:
317 
318  Irp - a pointer to the FxIrp
319 
320 Returns:
321 
322  NTSTATUS
323 
324 --*/
325 
326 {
327  FxPkgFdo* pThis;
329 
330  pThis = (FxPkgFdo*) This;
331 
332  status = pThis->SendIrpSynchronously(Irp);
333 
334  if (status == STATUS_NOT_SUPPORTED) {
335  //
336  // Morph into a successful code so that we process the request
337  //
339  Irp->SetStatus(status);
340  }
341 
342  if (NT_SUCCESS(status)) {
344  }
345  else {
347  This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
348  "Lower stack returned error for query pnp device state, %!STATUS!",
349  status);
350  }
351 
352  //
353  // Since we already sent the request down the stack, we must complete it
354  // now.
355  //
356  return pThis->CompletePnpRequest(Irp, status);
357 }
358 
360 NTSTATUS
363  )
364 /*++
365 
366 
367 
368 
369 
370 
371 
372 
373 Routine Description:
374 
375  After creating a FxPkgFdo, the driver writer will initialize it by passing
376  a set of driver callbacks that allow the driver writer to customize the
377  behavior when handling certain IRPs.
378 
379  This is the place to do any initialization that might fail.
380 
381 Arguments:
382 
383  Device - a pointer to the FxDevice
384 
385  DispatchTable - a driver supplied table of callbacks
386 
387 Returns:
388 
389  NTSTATUS
390 
391 --*/
392 {
395  size_t totalDescriptionSize = 0;
396  WDFCHILDLIST hList;
398 
400 
402  if (!NT_SUCCESS(status)) {
403  return status;
404  }
405 
407  if (!NT_SUCCESS(status)) {
408  return status;
409  }
410 
411  #pragma prefast(suppress: __WARNING_PASSING_FUNCTION_UNEXPECTED_NULL, "Static child lists do not use the EvtChildListCreateDevice callback")
413  sizeof(FxStaticChildDescription),
414  NULL);
415 
417  &config,
419  if (!NT_SUCCESS(status)) {
420  return status;
421  }
422 
424  pGlobals,
427  m_Device,
428  &config,
429  TRUE);
430  if (!NT_SUCCESS(status)) {
431  return status;
432  }
433 
435  (WDFOBJECT*) &hList,
436  m_Device);
437 
438  if (!NT_SUCCESS(status)) {
441 
442  return status;
443  }
444 
445  //
446  // This will be released in the destructor
447  //
448  m_StaticDeviceList->ADDREF(this);
449 
450  return status;
451 }
452 
454 NTSTATUS
456  VOID
457  )
458 {
459 // __REACTOS__ : not supported
460 // WDF_DSF_INTERFACE dsfInterface;
461 // NTSTATUS status;
462 // BOOLEAN derefQI = FALSE;
463 
464 // RtlZeroMemory(&dsfInterface, sizeof(dsfInterface));
465 
466 // //
467 // // Since there are some stacks that are not PnP re-entrant (like USBHUB,
468 // // xpsp2), we specify that the QI goes only to our attached device and
469 // // not to the top of the stack as a normal QI irp would.
470 // //
471 // // We also do this a preventative measure for other stacks we don't know
472 // // about internally and do not have access to when testing.
473 // //
474 // status = m_Device->QueryForInterface(&GUID_WDF_DSF_INTERFACE,
475 // (PINTERFACE) &dsfInterface,
476 // sizeof(dsfInterface),
477 // WDM_DSF_INTERFACE_V1_0,
478 // NULL,
479 // m_Device->GetAttachedDevice()
480 // );
481 
482 // if (status == STATUS_NOT_SUPPORTED) {
483 // DoTraceLevelMessage(
484 // GetDriverGlobals(), TRACE_LEVEL_WARNING, TRACINGPNP,
485 // "Lower stack does not have a DSF interface");
486 // status = STATUS_SUCCESS;
487 // goto Done;
488 // }
489 
490 // if (!NT_SUCCESS(status)) {
491 // DoTraceLevelMessage(
492 // GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
493 // "Lower stack returned an error for query DSF interface, %!STATUS!",
494 // status);
495 // goto Done;
496 // }
497 
498 // derefQI = TRUE;
499 
500 // //
501 // // Basic run time checks.
502 // //
503 // if (dsfInterface.Interface.Version != WDM_DSF_INTERFACE_V1_0) {
504 // status = STATUS_REVISION_MISMATCH;
505 // DoTraceLevelMessage(
506 // GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
507 // "Lower DSF stack supports v(%x), requested v(%x), %!STATUS!",
508 // dsfInterface.Interface.Version,
509 // WDM_DSF_INTERFACE_V1_0,
510 // status);
511 // goto Done;
512 // }
513 
514 // //
515 // // Ex functions should be both set or cleared.
516 // // Active/Inactive functions should be both set or cleared.
517 // // Ex function must be present.
518 // // Note: !!(ptr) expression below converts ptr value to true/false value.
519 // // I.e., ptr==NULL to false and ptr!=NULL to true.
520 // //
521 // if (!((!!(dsfInterface.IoConnectInterruptEx) ==
522 // !!(dsfInterface.IoDisconnectInterruptEx)) &&
523 // (!!(dsfInterface.IoReportInterruptActive) ==
524 // !!(dsfInterface.IoReportInterruptInactive)) &&
525 // (dsfInterface.IoConnectInterruptEx != NULL)
526 // )) {
527 // status = STATUS_DATA_ERROR;
528 // DoTraceLevelMessage(
529 // GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
530 // "Function mismatch detected in DSF interface, %!STATUS!",
531 // status);
532 // goto Done;
533 // }
534 
535 // //
536 // // Info is correct.
537 // //
538 // m_IoConnectInterruptEx = dsfInterface.IoConnectInterruptEx;
539 // m_IoDisconnectInterruptEx = dsfInterface.IoDisconnectInterruptEx;
540 
541 // //
542 // // If DSF interface provides active/inactive functions then use them
543 // //
544 // if (dsfInterface.IoReportInterruptActive != NULL)
545 // {
546 // m_IoReportInterruptActive = dsfInterface.IoReportInterruptActive;
547 // m_IoReportInterruptInactive = dsfInterface.IoReportInterruptInactive;
548 // }
549 
550 // Done:
551 
552 // //
553 // // The contract with the DSF layer is to release the interface right away;
554 // // the embedded interrupt function ptrs will be valid until this driver is
555 // // unloaded.
556 // //
557 // if (derefQI) {
558 // dsfInterface.Interface.InterfaceDereference(dsfInterface.Interface.Context);
559 // }
560 
561 // return status;
562  return STATUS_NOT_IMPLEMENTED;
563 }
564 
566 NTSTATUS
568  VOID
569  )
570 /*++
571 
572 Routine Description:
573  This routine asks the PDO to ask its parent bus driver to Surprise-Remove
574  and re-enumerate the PDO. This will be done only at the point of
575  catastrophic software failure, and occasionally after catastrophic hardware
576  failure.
577 
578 Arguments:
579  None
580 
581 Return Value:
582  status
583 
584  --*/
585 {
587 
589 
590  if (pInterface->SurpriseRemoveAndReenumerateSelf != NULL) {
591  pInterface->SurpriseRemoveAndReenumerateSelf(pInterface->Context);
592 
593  return STATUS_SUCCESS;
594  }
595 
596  return STATUS_NOT_SUPPORTED;
597 }
598 
CfxDevice * m_Device
Definition: fxobject.hpp:329
VOID HandleQueryCapabilitiesCompletion(__inout FxIrp *Irp)
Definition: fxpkgfdo.cpp:613
virtual _Must_inspect_result_ NTSTATUS AskParentToRemoveAndReenumerate(VOID)
Definition: fxpkgfdokm.cpp:567
_Must_inspect_result_ NTSTATUS QueryForDsfInterface(VOID)
Definition: fxpkgfdokm.cpp:455
virtual VOID DeleteObject(VOID)
return STATUS_NOT_SUPPORTED
static _Must_inspect_result_ NTSTATUS _PnpQueryCapabilitiesCompletionRoutine(__in MdDeviceObject DeviceObject, __inout MdIrp Irp, __inout PVOID Context)
Definition: fxpkgfdokm.cpp:227
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct config_s config
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
NTSTATUS FilterResourceRequirements(__in IO_RESOURCE_REQUIREMENTS_LIST **IoList)
Definition: fxpkgpnpkm.cpp:16
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
LONG NTSTATUS
Definition: precomp.h:26
REENUMERATE_SELF_INTERFACE_STANDARD m_SurpriseRemoveAndReenumerateSelfInterface
Definition: fxpkgfdo.hpp:57
Definition: fxirp.hpp:28
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST
_Must_inspect_result_ NTSTATUS Invoke(__in WDFDEVICE Device, __in WDFIORESREQLIST Collection)
FxIoResReqList * pIoResReqList
PINTERFACE pInterface
VOID HandleQueryPnpDeviceStateCompletion(__inout FxIrp *Irp)
Definition: fxpkgfdo.cpp:763
virtual _Must_inspect_result_ NTSTATUS Initialize(__in PWDFDEVICE_INIT DeviceInit)
Definition: fxpkgpnp.cpp:349
uint32_t ULONG_PTR
Definition: typedefs.h:65
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
PFN_WDF_DEVICE_FILTER_RESOURCE_REQUIREMENTS m_Method
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
return STATUS_NOT_IMPLEMENTED
#define FALSE
Definition: types.h:117
_Must_inspect_result_ NTSTATUS PnpFilterResourceRequirements(__inout FxIrp *Irp)
Definition: fxpkgfdokm.cpp:43
_In_ PIRP Irp
Definition: csq.h:116
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
BOOLEAN IsChanged(VOID)
Definition: fxresource.hpp:335
IWudfIrp * MdIrp
Definition: mxum.h:103
FxPnpDeviceFilterResourceRequirements m_DeviceFilterRemoveResourceRequirements
Definition: fxpkgfdo.hpp:65
_Must_inspect_result_ PIO_RESOURCE_REQUIREMENTS_LIST CreateWdmList(VOID)
_Must_inspect_result_ NTSTATUS PnpQueryCapabilities(__inout FxIrp *Irp)
Definition: fxpkgfdokm.cpp:244
_Must_inspect_result_ NTSTATUS AllocateEnumInfo(VOID)
Definition: fxpkgpnp.cpp:4920
FxPnpDeviceFilterResourceRequirements m_DeviceFilterAddResourceRequirements
Definition: fxpkgfdo.hpp:63
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID HandleQueryCapabilities(__inout FxIrp *Irp)
Definition: fxpkgfdo.cpp:572
#define __inout
Definition: dbghelp.h:50
#define _Must_inspect_result_
Definition: ms_sal.h:558
PFX_DRIVER_GLOBALS pGlobals
virtual _Must_inspect_result_ NTSTATUS Initialize(__in PWDFDEVICE_INIT DeviceInit)
Definition: fxpkgfdokm.cpp:361
static _Must_inspect_result_ NTSTATUS _PnpQueryPnpDeviceState(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgfdokm.cpp:305
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
HWND hList
Definition: livecd.c:10
#define TRACINGPNP
Definition: dbgtrace.h:67
static _Must_inspect_result_ NTSTATUS _PnpQueryPnpDeviceStateCompletionRoutine(__in MdDeviceObject DeviceObject, __inout MdIrp Irp, __inout PVOID Context)
Definition: fxpkgfdokm.cpp:288
FxChildList * m_StaticDeviceList
Definition: fxpkgfdo.hpp:42
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
WDFIORESREQLIST GetHandle(VOID)
Definition: fxresource.hpp:691
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
static _Must_inspect_result_ NTSTATUS _CreateAndInit(__out FxChildList **ChildList, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES ListAttributes, __in size_t TotalDescriptionSize, __in CfxDevice *Device, __in PWDF_CHILD_LIST_CONFIG ListConfig, __in BOOLEAN Static=FALSE)
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
static _Must_inspect_result_ NTSTATUS _ComputeTotalDescriptionSize(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_CHILD_LIST_CONFIG Config, __in size_t *TotalDescriptionSize)
_In_ PWDFDEVICE_INIT DeviceInit
Definition: wdfcontrol.h:113
#define STATUS_SUCCESS
Definition: shellext.h:65
virtual _Must_inspect_result_ NTSTATUS SendIrpSynchronously(__inout FxIrp *Irp)
Definition: fxpkgfdo.cpp:248
PVOID Context
Definition: miniport.h:123
static _Must_inspect_result_ FxIoResReqList * _CreateFromWdmList(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PIO_RESOURCE_REQUIREMENTS_LIST WdmRequirementsList, __in UCHAR AccessFlags)
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS CompletePnpRequest(__inout FxIrp *Irp, __in NTSTATUS Status)
Definition: fxpkgpnp.cpp:5752
FORCEINLINE VOID WDF_CHILD_LIST_CONFIG_INIT(_Out_ PWDF_CHILD_LIST_CONFIG Config, _In_ ULONG IdentificationDescriptionSize, _In_ PFN_WDF_CHILD_LIST_CREATE_DEVICE EvtChildListCreateDevice)
Definition: wdfchildlist.h:415
size_t totalDescriptionSize
Definition: ps.c:97