ReactOS 0.4.15-dev-8236-g99f0937
fxpkgpdokm.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxPkgPdoKM.cpp
8
9Abstract:
10
11 This module implements the Pnp package for Pdo devices.
12
13Author:
14
15
16
17Environment:
18
19 Kernel mode only
20
21Revision History:
22
23
24
25--*/
26
27#include "../pnppriv.hpp"
28#include <wdmguid.h>
29
30// Tracing support
31#if defined(EVENT_TRACING)
32extern "C" {
33#include "FxPkgPdoKM.tmh"
34}
35#endif
36
42 )
43{
44 return ((FxPkgPdo*) This)->PnpQueryResources(Irp);
45}
46
51 )
52
53/*++
54
55Routine 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
60Arguments:
61
62 Irp - a pointer to the FxIrp
63
64Returns:
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
91 if (!NT_SUCCESS(status)) {
92 goto exit;
93 }
94
96
97 if (NT_SUCCESS(status)) {
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);
127}
128
134 )
135{
136 return ((FxPkgPdo*) This)->PnpQueryResourceRequirements(Irp);
137}
138
143 )
144
145/*++
146
147Routine 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
153Arguments:
154
155 Irp - a pointer to the FxIrp
156
157Returns:
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!",
256 break;
257 }
258 }
259
261
262 if (!NT_SUCCESS(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 //
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:
339}
340
346 )
347/*++
348
349Routine Description:
350 Filter resource requirements for the PDO. A chance to further muck with
351 the resources assigned to the device.
352
353Arguments:
354 This - the package
355
356 Irp - the request
357
358Return 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
386}
387
LONG NTSTATUS
Definition: precomp.h:26
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
MdDeviceObject __inline GetPhysicalDevice(VOID)
Definition: fxdevice.hpp:228
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
UNICODE_STRING m_SymbolicLinkName
static FxDeviceInterface * _FromEntry(__in PSINGLE_LIST_ENTRY Entry)
_Must_inspect_result_ NTSTATUS Register(__in MdDeviceObject Pdo)
BOOLEAN m_PdoKnown
Definition: fxdevice.hpp:599
_Must_inspect_result_ PIO_RESOURCE_REQUIREMENTS_LIST CreateWdmList(VOID)
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
Definition: fxirp.hpp:28
virtual VOID DeleteObject(VOID)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
_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
_Must_inspect_result_ NTSTATUS PnpQueryResourceRequirements(__inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:141
static _Must_inspect_result_ NTSTATUS _PnpFilterResourceRequirements(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:343
static _Must_inspect_result_ NTSTATUS _PnpQueryResourceRequirements(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:131
static _Must_inspect_result_ NTSTATUS _PnpQueryResources(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:39
FxPnpDeviceResourceRequirementsQuery m_DeviceResourceRequirementsQuery
Definition: fxpkgpdo.hpp:49
_Must_inspect_result_ NTSTATUS PnpQueryResources(__inout FxIrp *Irp)
Definition: fxpkgpdokm.cpp:49
FxPnpDeviceResourcesQuery m_DeviceResourcesQuery
Definition: fxpkgpdo.hpp:48
SINGLE_LIST_ENTRY m_DeviceInterfaceHead
Definition: fxpkgpnp.hpp:4126
FxWaitLockInternal m_DeviceInterfaceLock
Definition: fxpkgpnp.hpp:4124
NTSTATUS CompletePnpRequest(__inout FxIrp *Irp, __in NTSTATUS Status)
Definition: fxpkgpnp.cpp:5752
PFN_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY m_Method
_Must_inspect_result_ NTSTATUS Invoke(__in WDFDEVICE Device, __in WDFIORESREQLIST Collection)
PFN_WDF_DEVICE_RESOURCES_QUERY m_Method
_Must_inspect_result_ NTSTATUS Invoke(__in WDFDEVICE Device, __in WDFCMRESLIST Collection)
Definition: list.h:37
_In_ PIRP Irp
Definition: csq.h:116
#define __inout
Definition: dbghelp.h:50
#define TRACINGPNP
Definition: dbgtrace.h:67
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxDeviceInterface * pDeviceInterface
PSINGLE_LIST_ENTRY ple
@ FxResourceAllAccessAllowed
Definition: fxresource.hpp:277
FxIoResList * pResList
FxIoResReqList * pIoResReqList
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define list
Definition: rosglue.h:35
#define exit(n)
Definition: config.h:202
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
Definition: ps.c:97
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105