1 /*++
2
3 Copyright (c) Microsoft Corporation
4
5 Module Name:
6
7 FxDeviceInit.cpp
8
9 Abstract:
10 Internals for WDFDEVICE_INIT
11
12 Author:
13
14
15
16 Environment:
17
18 Both kernel and user mode
19
20 Revision History:
21
22 --*/
23
24 #include "coreprivshared.hpp"
25
26 extern "C" {
27 // #include "FxDeviceInit.tmh"
28 }
29
WDFDEVICE_INIT(__in FxDriver * Driver)30 WDFDEVICE_INIT::WDFDEVICE_INIT(
31 __in FxDriver* Driver
32 ) :
33 Driver(Driver)
34 {
35 DriverGlobals = Driver->GetDriverGlobals();
36
37 ReadWriteIoType = WdfDeviceIoBuffered;
38 PowerPageable = TRUE;
39 Inrush = FALSE;
40 DeviceType = FILE_DEVICE_UNKNOWN;
41 Characteristics = FILE_DEVICE_SECURE_OPEN;
42
43 RtlZeroMemory(&FileObject, sizeof(FileObject));
44 FileObject.AutoForwardCleanupClose = WdfUseDefault;
45
46 DeviceName = NULL;
47 CreatedDevice = NULL;
48
49 CreatedOnStack = FALSE;
50 Exclusive = FALSE;
51
52 RequiresSelfIoTarget = FALSE;
53
54 RemoveLockOptionFlags = 0;
55
56 RtlZeroMemory(&PnpPower.PnpPowerEventCallbacks, sizeof(PnpPower.PnpPowerEventCallbacks));
57 RtlZeroMemory(&PnpPower.PolicyEventCallbacks, sizeof(PnpPower.PolicyEventCallbacks));
58 PnpPower.PnpStateCallbacks = NULL;
59 PnpPower.PowerStateCallbacks = NULL;
60 PnpPower.PowerPolicyStateCallbacks = NULL;
61
62 PnpPower.PowerPolicyOwner = WdfUseDefault;
63
64 InitType = FxDeviceInitTypeFdo;
65
66 RtlZeroMemory(&Fdo.EventCallbacks, sizeof(Fdo.EventCallbacks));
67 RtlZeroMemory(&Fdo.ListConfig, sizeof(Fdo.ListConfig));
68 RtlZeroMemory(&Fdo.ListConfigAttributes, sizeof(Fdo.ListConfigAttributes));
69 Fdo.Filter = FALSE;
70
71 RtlZeroMemory(&Pdo.EventCallbacks, sizeof(Pdo.EventCallbacks));
72 Pdo.Raw = FALSE;
73 Pdo.Static = FALSE;
74 Pdo.DeviceID = NULL;
75 Pdo.InstanceID = NULL;
76 Pdo.ContainerID = NULL;
77 Pdo.DefaultLocale = 0x0;
78 Pdo.DescriptionEntry = NULL;
79 Pdo.ForwardRequestToParent = FALSE;
80
81 RtlZeroMemory(&Security, sizeof(Security));
82
83 RtlZeroMemory(&RequestAttributes, sizeof(RequestAttributes));
84
85 PreprocessInfo = NULL;
86
87 IoInCallerContextCallback = NULL;
88
89 InitializeListHead(&CxDeviceInitListHead);
90
91 ReleaseHardwareOrderOnFailure = WdfReleaseHardwareOrderOnFailureEarly;
92
93 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
94
95 DeviceControlIoType = WdfDeviceIoBuffered;
96 DirectTransferThreshold = 0;
97
98 DevStack = NULL;
99
100 KernelDeviceName = NULL;
101
102 PdoKey = NULL;
103
104 DevInstanceID = NULL;
105
106 DriverID = 0;
107 #endif
108 }
109
~WDFDEVICE_INIT()110 WDFDEVICE_INIT::~WDFDEVICE_INIT()
111 {
112 PLIST_ENTRY next;
113
114 if (PnpPower.PnpStateCallbacks != NULL) {
115 delete PnpPower.PnpStateCallbacks;
116 }
117
118 if (PnpPower.PowerStateCallbacks != NULL) {
119 delete PnpPower.PowerStateCallbacks;
120 }
121
122 if (PnpPower.PowerPolicyStateCallbacks != NULL) {
123 delete PnpPower.PowerPolicyStateCallbacks;
124 }
125
126 if (DeviceName != NULL) {
127 DeviceName->DeleteObject();
128 }
129 if (Pdo.DeviceID != NULL) {
130 Pdo.DeviceID->DeleteObject();
131 }
132 if (Pdo.InstanceID != NULL) {
133 Pdo.InstanceID->DeleteObject();
134 }
135 if (Pdo.ContainerID != NULL) {
136 Pdo.ContainerID->DeleteObject();
137 }
138
139 FxDeviceText::_CleanupList(&Pdo.DeviceText);
140
141 if (Security.Sddl != NULL) {
142 Security.Sddl->DeleteObject();
143 }
144 if (PreprocessInfo != NULL) {
145 delete PreprocessInfo;
146 }
147
148 while(!IsListEmpty(&CxDeviceInitListHead)) {
149 next = RemoveHeadList(&CxDeviceInitListHead);
150 PWDFCXDEVICE_INIT cxInit;
151 cxInit = CONTAINING_RECORD(next, WDFCXDEVICE_INIT, ListEntry);
152 InitializeListHead(next);
153 delete cxInit;
154 }
155
156 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
157 delete [] KernelDeviceName;
158 delete [] ConfigRegistryPath;
159 delete [] DevInstanceID;
160
161 if (PdoKey != NULL) {
162 RegCloseKey(PdoKey);
163 PdoKey = NULL;
164 }
165 #endif
166
167 }
168
169 _Must_inspect_result_
170 NTSTATUS
AssignName(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in const UNICODE_STRING * Name)171 WDFDEVICE_INIT::AssignName(
172 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
173 __in const UNICODE_STRING* Name
174 )
175 {
176 if (DeviceName == NULL) {
177 DeviceName = new(FxDriverGlobals, WDF_NO_OBJECT_ATTRIBUTES)
178 FxString(FxDriverGlobals);
179
180 if (DeviceName == NULL) {
181 NTSTATUS status;
182
183 status = STATUS_INSUFFICIENT_RESOURCES;
184
185 DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
186 "DeviceName is NULL, %!STATUS!", status);
187
188 return status;
189 }
190
191 //
192 // Clear out the autogenerate flag since we have a specific name
193 //
194 Characteristics &= ~FILE_AUTOGENERATED_DEVICE_NAME;
195 }
196
197 return DeviceName->Assign(Name);
198 }
199
200 _Must_inspect_result_
201 PWDFDEVICE_INIT
_AllocateControlDeviceInit(__in FxDriver * Driver,__in const UNICODE_STRING * SDDLString)202 WDFDEVICE_INIT::_AllocateControlDeviceInit(
203 __in FxDriver* Driver,
204 __in const UNICODE_STRING* SDDLString
205 )
206 {
207 PFX_DRIVER_GLOBALS pFxDriverGlobals;
208 PWDFDEVICE_INIT pInit;
209 NTSTATUS status;
210
211 pFxDriverGlobals = Driver->GetDriverGlobals();
212
213 pInit = new(pFxDriverGlobals) WDFDEVICE_INIT(Driver);
214
215 if (pInit == NULL) {
216 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
217 "WDFDRIVER 0x%p couldn't allocate WDFDEVICE_INIT",
218 Driver);
219 return NULL;
220 }
221
222 pInit->InitType = FxDeviceInitTypeControlDevice;
223
224 //
225 // Since we require and SDLL string, initialize to autogenerated device
226 // name so the driver doesn't have to worry about creating a name if they
227 // don't want it (useful if creating a DO for WMI tracing for instance).
228 //
229 pInit->Characteristics |= FILE_AUTOGENERATED_DEVICE_NAME;
230
231 pInit->Security.Sddl = new(pFxDriverGlobals, WDF_NO_OBJECT_ATTRIBUTES)
232 FxString(pFxDriverGlobals);
233
234 if (pInit->Security.Sddl != NULL) {
235 status = pInit->Security.Sddl->Assign(SDDLString);
236 }
237 else {
238 status = STATUS_INSUFFICIENT_RESOURCES;
239 DoTraceLevelMessage(
240 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE,
241 "WDFDRIVER 0x%p couldn't create Security String object %!STATUS!",
242 Driver, status);
243 }
244
245 if (!NT_SUCCESS(status)) {
246 delete pInit;
247 pInit = NULL;
248 }
249
250 return pInit;
251 }
252
253 BOOLEAN
ShouldCreateSecure(VOID)254 WDFDEVICE_INIT::ShouldCreateSecure(
255 VOID
256 )
257 {
258 //
259 // Driver explicitly set a class or SDDL, we have to create a secure
260 // device. This will be true for all control devices (SDDL required)
261 // and raw PDOs (class required), could be true for FDOs or filters as
262 // well.
263 //
264 if (Security.DeviceClassSet || Security.Sddl != NULL) {
265 return TRUE;
266 }
267
268 //
269 // See if there is a name for the device
270 //
271 if (HasName()) {
272 if (IsPdoInit()) {
273
274
275
276
277
278
279
280
281
282
283
284
285
286 ASSERT(Pdo.Raw == FALSE);
287
288 DoTraceLevelMessage(
289 DriverGlobals,
290 TRACE_LEVEL_WARNING,
291 TRACINGDEVICE,
292 "WDFDRIVER 0x%p asked for a named device object, but the PDO "
293 "will be created without a name because an SDDL string has not "
294 "been specified for the PDO.",
295 Driver
296 );
297 return FALSE;
298 }
299 else {
300 //
301 // We are creating a named FDO or filter
302 //
303 ASSERT(IsFdoInit());
304 return TRUE;
305 }
306 }
307
308 //
309 // No name involved (FDO or filter)
310 //
311 ASSERT(IsFdoInit());
312
313 return FALSE;
314 }
315
316 VOID
AddCxDeviceInit(__in PWDFCXDEVICE_INIT CxDeviceInit)317 WDFDEVICE_INIT::AddCxDeviceInit(
318 __in PWDFCXDEVICE_INIT CxDeviceInit
319 )
320 {
321 InsertHeadList(&CxDeviceInitListHead, &CxDeviceInit->ListEntry);
322 }
323
324