1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxDriverKm.cpp
8 
9 Abstract:
10 
11     This is the main driver framework.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19     Kernel mode only
20 
21 Revision History:
22 
23 
24 
25 --*/
26 
27 #include "coreprivshared.hpp"
28 #include "fxiotarget.hpp"
29 
30 // Tracing support
31 extern "C" {
32 // #include "FxDriverKm.tmh"
33 }
34 
35 _Must_inspect_result_
36 NTSTATUS
37 STDCALL
AddDevice(__in MdDriverObject DriverObject,__in MdDeviceObject PhysicalDeviceObject)38 FxDriver::AddDevice(
39     __in MdDriverObject DriverObject,
40     __in MdDeviceObject PhysicalDeviceObject
41     )
42 {
43     FxDriver *pDriver;
44 
45     pDriver = FxDriver::GetFxDriver(DriverObject);
46 
47     if (pDriver != NULL) {
48         return pDriver->AddDevice(PhysicalDeviceObject);
49     }
50 
51     return STATUS_UNSUCCESSFUL;
52 }
53 
54 _Must_inspect_result_
55 NTSTATUS
AddDevice(_In_ MdDeviceObject PhysicalDeviceObject)56 FxDriver::AddDevice(
57     _In_ MdDeviceObject PhysicalDeviceObject
58     )
59 {
60     WDFDEVICE_INIT init(this);
61     FxDevice* pDevice;
62     NTSTATUS status;
63 
64     DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
65                         "Enter AddDevice PDO %p", PhysicalDeviceObject);
66 
67     pDevice = NULL;
68     init.CreatedOnStack = TRUE;
69 
70     init.InitType = FxDeviceInitTypeFdo;
71     init.Fdo.PhysicalDevice = PhysicalDeviceObject;
72 
73     status = m_DriverDeviceAdd.Invoke(GetHandle(), &init);
74 
75     //
76     // Caller returned w/out creating a device, we are done.  Returning
77     // STATUS_SUCCESS w/out creating a device and attaching to the stack is OK,
78     // especially for filter drivers which selectively attach to devices.
79     //
80     if (init.CreatedDevice == NULL) {
81         DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_WARNING, TRACINGPNP,
82                             "Driver did not create a device in "
83                             "EvtDriverAddDevice, status %!STATUS!", status);
84 
85         //
86         // We do not let filters affect the building of the rest of the stack.
87         // If they return error, we convert it to STATUS_SUCCESS.
88         //
89         if (init.Fdo.Filter && !NT_SUCCESS(status)) {
90             DoTraceLevelMessage(
91                 GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP,
92                 "Filter returned %!STATUS! without creating a WDFDEVICE, "
93                 "converting to STATUS_SUCCESS", status);
94             status = STATUS_SUCCESS;
95         }
96 
97         return status;
98     }
99 
100     pDevice = init.CreatedDevice;
101 
102     if (NT_SUCCESS(status)) {
103         //
104         // Make sure that DO_DEVICE_INITIALIZING is cleared.
105         // FxDevice::FdoInitialize does not do this b/c the driver writer may
106         // want the bit set until sometime after WdfDeviceCreate returns
107         //
108         pDevice->FinishInitializing();
109     }
110     else {
111         //
112         // Created a device, but returned error.
113         //
114         ASSERT(pDevice->IsPnp());
115         ASSERT(pDevice->m_CurrentPnpState == WdfDevStatePnpInit);
116 
117         status = pDevice->DeleteDeviceFromFailedCreate(status, TRUE);
118         pDevice = NULL;
119     }
120 
121     DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
122                         "Exit, status %!STATUS!", status);
123 
124     return status;
125 }
126 
127 
128 _Must_inspect_result_
129 NTSTATUS
AllocateDriverObjectExtensionAndStoreFxDriver(VOID)130 FxDriver::AllocateDriverObjectExtensionAndStoreFxDriver(
131     VOID
132     )
133 {
134     NTSTATUS status;
135     FxDriver** ppDriver;
136 
137     //
138     // Prefast is much happier if we take the size of the type rather then
139     // the size of the variable.
140     //
141     status = Mx::MxAllocateDriverObjectExtension( m_DriverObject.GetObject(),
142                                                   FX_DRIVER_ID,
143                                                   sizeof(FxDriver**),
144                                                   (PVOID*)&ppDriver);
145     if (!NT_SUCCESS(status)) {
146         return status;
147     }
148 
149     //
150     // If we succeeded in creating the driver object extension,
151     // then store our FxDriver pointer in the DriverObjectExtension.
152     //
153     *ppDriver = this;
154 
155     return STATUS_SUCCESS;
156 }
157 
158 FxDriver*
GetFxDriver(__in MdDriverObject DriverObject)159 FxDriver::GetFxDriver(
160     __in MdDriverObject DriverObject
161     )
162 {
163     FxDriver* objExt;
164     objExt = *(FxDriver **)Mx::MxGetDriverObjectExtension(DriverObject,
165                                                        FX_DRIVER_ID);
166     ASSERT(objExt != NULL);
167 
168     return objExt;
169 }
170 
171 
172