ReactOS  0.4.15-dev-3331-g8ebe441
fxpkgpdokm.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxPkgPdoKM.cpp
8 
9 Abstract:
10 
11  This module implements the Pnp package for Pdo devices.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19  Kernel mode only
20 
21 Revision History:
22 
23 
24 
25 --*/
26 
27 #include "../pnppriv.hpp"
28 #include <wdmguid.h>
29 
30 // Tracing support
31 #if defined(EVENT_TRACING)
32 extern "C" {
33 #include "FxPkgPdoKM.tmh"
34 }
35 #endif
36 
42  )
43 {
44  return ((FxPkgPdo*) This)->PnpQueryResources(Irp);
45 }
46 
51  )
52 
53 /*++
54 
55 Routine Description:
56 
57  This method is invoked in response to a Pnp QueryResources IRP. We return
58  the resources that the device is currently consuming.
59 
60 Arguments:
61 
62  Irp - a pointer to the FxIrp
63 
64 Returns:
65 
66  NTSTATUS
67 
68 --*/
69 
70 {
72  PCM_RESOURCE_LIST pWdmResourceList;
73  WDFCMRESLIST list;
75 
76  //
77  // It is only necessary to create a collection if the caller is interested
78  // in this callback.
79  //
81  return CompletePnpRequest(Irp, Irp->GetStatus());
82  }
83 
84  pWdmResourceList = NULL;
85 
88  m_Device,
91  if (!NT_SUCCESS(status)) {
92  goto exit;
93  }
94 
96 
97  if (NT_SUCCESS(status)) {
99  m_Device->GetHandle(), list);
100 
101  if (NT_SUCCESS(status)) {
102  //
103  // Walk the resource collection and create the appropriate
104  // CM_RESOURCE_LIST.
105  //
106  if (pResList->Count()) {
107  pWdmResourceList = pResList->CreateWdmList();
108  }
109  else {
110  //
111  // The driver didn't add any resources, so we'll just
112  // ignore this Irp.
113  //
114  // Return that status that was passed in.
115  //
116  status = Irp->GetStatus();
117  pWdmResourceList = (PCM_RESOURCE_LIST) Irp->GetInformation();
118  }
119  }
120  }
121 
123 
124  exit:
125  Irp->SetInformation((ULONG_PTR) pWdmResourceList);
126  return CompletePnpRequest(Irp, status);
127 }
128 
130 NTSTATUS
133  __inout FxIrp *Irp
134  )
135 {
136  return ((FxPkgPdo*) This)->PnpQueryResourceRequirements(Irp);
137 }
138 
140 NTSTATUS
142  __inout FxIrp *Irp
143  )
144 
145 /*++
146 
147 Routine Description:
148 
149  This method is invoked in response to a Pnp QueryResourceRequirements IRP.
150  We return the set (of sets) of possible resources that we could accept
151  which would allow our device to work.
152 
153 Arguments:
154 
155  Irp - a pointer to the FxIrp
156 
157 Returns:
158 
159  NTSTATUS
160 
161 --*/
162 
163 {
164  PIO_RESOURCE_REQUIREMENTS_LIST pWdmRequirementsList;
168 
170 
172 
173 
174 
175 
176  // We know for sure that the PDO is known to pnp now because it has received
177  // this query resource requirements request.
179 
180  //
181  // Now that it is a known PDO, we can register interfaces on it whose
182  // registration was delayed because the PDO was unknown at the time of the
183  // call to WdfDeviceCreateDeviceInterface. If it is not the first time
184  // then we re-register (see comments below for reason).
185  //
186  for (ple = m_DeviceInterfaceHead.Next; ple != NULL; ple = ple->Next) {
188 
190 
191  //
192  // At this time the interface may be in registered or unregistered state.
193  // The reason being that pnp may unregister the interface from underneath
194  // during the life of PDO (note that drivers never unregister explicitly
195  // as there is no unregistration API, and the scenarios in which it can
196  // happen are given below). Therefore WDF needs to re-register the interface,
197  // otherwise driver may end up with an unregistered interface and fail to
198  // enable interface.
199  //
200  // Pnp can unregister the interface in following cases:
201  // 1. The driver is uninstalled, and re-installed
202  // In this case, the stack is torn down but the PDO is not
203  // deleted. Pnp deletes the interface registration, however WDF
204  // doesn't delete the interface structure because it is deleted as
205  // part of PDO deletion in destructor. When the driver is re-installed
206  // Pnp sends another query resource requirements irp and WDF needs to
207  // re-register at this time.
208  //
209  // 2. Pnp couldn't find a driver and loaded a NULL driver while
210  // waiting for reinstall to happen from WU. This is similar to case above
211  // except that the pnp activities are transparent to user.
212  // In this case, PDO was never started. However it did get
213  // the query resource requirements irp and therefore its interface
214  // was registered by WDF. Pnp deleted the interface registration
215  // when installing NULL driver. When pnp finally finds a driver from
216  // WU, it sends another query resource requirement irp. At this time,
217  // WDF needs to re-register.
218  //
219  // In both the above cases, WDF has to re-register (and free previous
220  // sym link) when query resource requirements irp arrives again. Note
221  // that Pnp doesn't delete the interface registration during disable,
222  // s/w surprise-removal, or resource rebalance. In case of resource
223  // rebalance, query resource requirement irp is sent after stop, and
224  // WDF will end up registering again even though pnp did not unregister
225  // the interface. This is fine because kernel API for registration
226  // allows multiple calls to register, and in case registration already
227  // exists it returns informational status (not error status)
228  // STATUS_OBJECT_NAME_EXISTS and also returns the same symbolic link.
229  //
230  //
231  // Free the symbolic link if already present
232  //
237  }
238 
239  //
240  // Register. Note that if the interface was already registered, the
241  // call to IoRegisterDeviceInterface will return informational status
242  // (not error status) STATUS_OBJECT_NAME_EXISTS and also return the
243  // symbolic link.
244  //
247  );
248 
249  if (!NT_SUCCESS(status)) {
252  "could not register device interface on PDO WDFDEVICE %p, "
253  "!devobj %p, failing IRP_MN_QUERY_RESOURCE_REQUIREMENTS %!STATUS!",
254  m_Device->GetHandle(),
256  break;
257  }
258  }
259 
261 
262  if (!NT_SUCCESS(status)) {
263  return CompletePnpRequest(Irp, status);
264  }
265 
266  //
267  // Driver writer is not interested in this callback, forgoe the allocation
268  // of the FxCollection and complete the request here.
269  //
271  return CompletePnpRequest(Irp, status);
272  }
273 
274  pWdmRequirementsList = NULL;
275 
276  //
277  // Create a collection which will be populated by the
278  // bus driver.
279  //
284  if (!NT_SUCCESS(status)) {
285  goto exit;
286  }
287 
288  WDFIORESREQLIST reqlist;
289 
290  //
291  // Get a handle to the collection that can be passed to the driver.
292  //
293  status = pIoResReqList->Commit(NULL, (PWDFOBJECT) &reqlist);
294 
295  //
296  // We control the object's state, this should never fail
297  //
300 
301  //
302  // Call the driver. The driver will populate the resource collection
303  // with a set of child collections which will contain each of the
304  // possible resource assignments.
305  //
307  m_Device->GetHandle(), reqlist);
308 
309  if (NT_SUCCESS(status)) {
310  if (pIoResReqList->Count()) {
311  //
312  // Create a IO_RESOURCE_REQUIREMENTS_LIST based on the
313  // contents of our collection.
314  //
315  pWdmRequirementsList = pIoResReqList->CreateWdmList();
316 
317  if (pWdmRequirementsList != NULL) {
318  Irp->SetInformation((ULONG_PTR) pWdmRequirementsList);
319  }
320  else {
322  }
323  }
324  else {
325  //
326  // The driver didn't add any resources, so we'll just
327  // ignore this request.
328  //
329  // Return the status that was passed in.
330  //
331  status = Irp->GetStatus();
332  }
333  }
334 
336 
337  exit:
338  return CompletePnpRequest(Irp, status);
339 }
340 
342 NTSTATUS
345  __inout FxIrp *Irp
346  )
347 /*++
348 
349 Routine Description:
350  Filter resource requirements for the PDO. A chance to further muck with
351  the resources assigned to the device.
352 
353 Arguments:
354  This - the package
355 
356  Irp - the request
357 
358 Return Value:
359  NTSTATUS
360 
361  --*/
362 {
364 
365  //
366  // Give the Framework objects a pass at the list.
367  //
368  status = ((FxPkgPdo*) This)->FilterResourceRequirements(
369  (PIO_RESOURCE_REQUIREMENTS_LIST*)(&Irp->GetIrp()->IoStatus.Information)
370  );
371 
372  if (NT_SUCCESS(status)) {
373  //
374  // Upon successful internal filtering, return the embedded status.
375  //
376  status = Irp->GetStatus();
377  }
378  else {
379  //
380  // Only on failure do we change the status of the irp
381  //
382  Irp->SetStatus(status);
383  }
384 
385  return ((FxPkgPdo*) This)->CompletePnpRequest(Irp, status);
386 }
387 
CfxDevice * m_Device
Definition: fxobject.hpp:329
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
virtual VOID DeleteObject(VOID)
_Must_inspect_result_ NTSTATUS Register(__in MdDeviceObject Pdo)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static FxDeviceInterface * _FromEntry(__in PSINGLE_LIST_ENTRY Entry)
_Must_inspect_result_ NTSTATUS PnpQueryResources(__inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:49
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
_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
FxPnpDeviceResourcesQuery m_DeviceResourcesQuery
Definition: fxpkgpdo.hpp:48
Definition: ntbasedef.h:628
_Must_inspect_result_ NTSTATUS Invoke(__in WDFDEVICE Device, __in WDFCMRESLIST Collection)
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
FxDeviceInterface * pDeviceInterface
LONG NTSTATUS
Definition: precomp.h:26
static _Must_inspect_result_ NTSTATUS _PnpFilterResourceRequirements(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:343
Definition: fxirp.hpp:28
FxIoResReqList * pIoResReqList
UNICODE_STRING m_SymbolicLinkName
PSINGLE_LIST_ENTRY ple
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ PIRP Irp
Definition: csq.h:116
_Must_inspect_result_ PIO_RESOURCE_REQUIREMENTS_LIST CreateWdmList(VOID)
PFN_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY m_Method
BOOLEAN m_PdoKnown
Definition: fxdevice.hpp:599
MdDeviceObject __inline GetPhysicalDevice(VOID)
Definition: fxdevice.hpp:228
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FxIoResList * pResList
FxWaitLockInternal m_DeviceInterfaceLock
Definition: fxpkgpnp.hpp:4124
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
SINGLE_LIST_ENTRY m_DeviceInterfaceHead
Definition: fxpkgpnp.hpp:4126
Definition: _list.h:228
#define __inout
Definition: dbghelp.h:50
#define _Must_inspect_result_
Definition: ms_sal.h:558
FxPnpDeviceResourceRequirementsQuery m_DeviceResourceRequirementsQuery
Definition: fxpkgpdo.hpp:49
static _Must_inspect_result_ NTSTATUS _PnpQueryResources(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:39
_Must_inspect_result_ NTSTATUS PnpQueryResourceRequirements(__inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:141
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define list
Definition: rosglue.h:35
#define NULL
Definition: types.h:112
PFN_WDF_DEVICE_RESOURCES_QUERY m_Method
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static _Must_inspect_result_ NTSTATUS _CreateAndInit(__in FxIoResReqList **ResourceReqList, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES ListAttributes, __in UCHAR AccessFlags)
Definition: fxresource.hpp:646
#define STATUS_SUCCESS
Definition: shellext.h:65
void exit(int exitcode)
Definition: _exit.c:33
_Must_inspect_result_ NTSTATUS Invoke(__in WDFDEVICE Device, __in WDFIORESREQLIST Collection)
static SERVICE_STATUS status
Definition: service.c:31
static _Must_inspect_result_ NTSTATUS _CreateAndInit(__in FxCmResList **ResourceList, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device, __in_opt PWDF_OBJECT_ATTRIBUTES ListAttributes, __in UCHAR AccessFlags)
Definition: fxresource.hpp:400
NTSTATUS CompletePnpRequest(__inout FxIrp *Irp, __in NTSTATUS Status)
Definition: fxpkgpnp.cpp:5752
static _Must_inspect_result_ NTSTATUS _PnpQueryResourceRequirements(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:131
Definition: ps.c:97