ReactOS  0.4.15-dev-3316-g067ca88
fxdriverapi.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxDriverApi.cpp
8 
9 Abstract:
10 
11  This module contains the "C" interface for the FxDriver object.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19  Both kernel and user mode
20 
21 Revision History:
22 
23 --*/
24 
25 #include "coreprivshared.hpp"
26 
27 // Tracing support
28 extern "C" {
29 #include <ntverp.h>
30 // #include "FxDriverApi.tmh"
31 }
32 
33 #include "fxtelemetry.hpp"
34 
35 //
36 // extern the whole file
37 //
38 extern "C" {
39 
40 //
41 // Driver Pool Allocations
42 //
43 
44 
46 PWSTR
47 STDCALL
48 WDFEXPORT(WdfDriverGetRegistryPath)(
49  __in
51  __in
52  WDFDRIVER Driver
53  )
54 {
55  DDI_ENTRY();
56 
60 
62  Driver,
64  (PVOID *)&pDriver,
66 
68  if (!NT_SUCCESS(status)) {
69  return NULL;
70  }
71 
73 }
74 
75 VOID
76 RosInitWdf();
77 
81 STDCALL
82 WDFEXPORT(WdfDriverCreate)(
83  __in
85  __in
87  __in
89  __in_opt
91  __in
93  __out_opt
94  WDFDRIVER* Driver
95  )
96 {
97  DDI_ENTRY();
98 
100  FxDriver *pDriver;
102  WDFDRIVER hDriver;
105 
106  RosInitWdf();
108 
109  hDriver = NULL;
111 
115 
116  //
117  // Validate the size of the input Driver Config structure. The size changed
118  // after v1.1. The size is the same for v1.1 and v1.0, verify that.
119  //
121 
122  if (DriverConfig->Size != sizeof(WDF_DRIVER_CONFIG)
123  &&
124  DriverConfig->Size != sizeof(WDF_DRIVER_CONFIG_V1_1)) {
125 
129  "WDF_DRIVER_CONFIG got Size %d, expected v1.1 size %d or cur ver size %d, %!STATUS!",
130  DriverConfig->Size,
132 
133  return status;
134  }
135 
136  //
137  // Validate the DriverInitFlags value in the Driver Config.
138  //
139  if ((DriverConfig->DriverInitFlags & ~validFlags) != 0) {
143  "DriverInitFlags 0x%x invalid, valid flags are 0x%x, %!STATUS!",
144  DriverConfig->DriverInitFlags, validFlags, status);
145  return status;
146  }
147 
149  if (!NT_SUCCESS(status)) {
150  return status;
151  }
152 
154  if (!NT_SUCCESS(status)) {
155  return status;
156  }
157 
158  //
159  // Driver and Public.Driver are set once WdfDriverCreate returns successfully.
160  // If they are set, that means this DDI has already been called for this
161  // client. Return an error if this occurrs.
162  //
164  pFxDriverGlobals->Public.Driver != NULL) {
165 
167 
169  "WdfDriverCreate can only be called one time per "
170  "WDM PDRIVER_OBJECT %p, %!STATUS!",
172 
173  return status;
174  }
175 
176  if (Driver != NULL) {
177  *Driver = NULL;
178  }
179 
180  //
181  // Initializing the tag requires initializing the driver name first.
182  //
184 
185  //
186  // Initialize the tag before any allocation so that we can use the correct
187  // tag value when allocating on behalf of the driver (for all allocations,
188  // including FxDriver).
189  //
190  // Use the client's driver tag value if they specified one. First check
191  // to make sure the size of the structure is the new size (vs the old size
192  // in v1.1).
193  //
194  // ' kdD' - was the default tag in many DDKs, don't allow its use.
195  //
196  if (DriverConfig->Size == sizeof(WDF_DRIVER_CONFIG) &&
197  DriverConfig->DriverPoolTag != 0x0 &&
198  DriverConfig->DriverPoolTag != ' kdD') {
199  //
200  // Copy directly using the driver's value
201  //
202  pFxDriverGlobals->Tag = DriverConfig->DriverPoolTag;
203  pFxDriverGlobals->Public.DriverTag = DriverConfig->DriverPoolTag;
204  }
205  else {
206  //
207  // Derive the value from the driver's service name
208  //
210  }
211 
212  //
213  // Check to see if this is an NT4 style device driver. If so, fail if they
214  // specified an AddDevice routine. If no dispatch override is set,
215  // do not do any checking at all.
216  //
218  DO_NOTHING();
219  }
220  else if ((DriverConfig->DriverInitFlags & WdfDriverInitNonPnpDriver) &&
221  DriverConfig->EvtDriverDeviceAdd != NULL) {
222 
224  "Invalid Driver flags or EvtDriverDeviceAdd callback already added"
225  "STATUS_INVALID_PARAMETER");
226 
228  }
229 
234  );
235 
236  if (!NT_SUCCESS(status)) {
237  return status;
238  }
239 
240  //
241  // FxDriver stores the driver wide configuration
242  //
244 
245  //
246  // FxDriver stores the driver wide configuration
247  //
250 
251  if (pDriver != NULL) {
252 
253  if (NT_SUCCESS(status)) {
254 
256 
257  if (NT_SUCCESS(status)) {
259  }
260  }
261  }
262  else {
264  }
265 
266  //
267  // Only return a valid handle on success. Upon error, release any memory
268  // and do not rely on any other function (like the driver unload routine) to
269  // be called.
270  //
272  //
273  // **** Note ****
274  // Do not introduce failures after this point without ensuring
275  // FxObject::DeleteFromFailedCreate has a chance to clear out any
276  // assigned callbacks on the object.
277  //
278 
279  //
280  // Store the WDFDRIVER and FxDriver* globally so the driver can retrieve
281  // it anytime.
282  //
284  pFxDriverGlobals->Public.Driver = hDriver;
285 
286  //
287  // Record the flags so that diagnostics knows what type of driver it is.
288  //
289  pFxDriverGlobals->Public.DriverFlags |= DriverConfig->DriverInitFlags;
290 
291  if (DriverConfig->DriverInitFlags &
293  //
294  // If there is no dispatch override or if it is an NT4 legacy style
295  // driver then we will not displace unload in the stub if one was not
296  // specified.
297  //
298  if (DriverConfig->EvtDriverUnload != NULL) {
299  pFxDriverGlobals->Public.DisplaceDriverUnload = TRUE;
300  }
301  else {
302  pFxDriverGlobals->Public.DisplaceDriverUnload = FALSE;
303  }
304  }
305  else {
306  pFxDriverGlobals->Public.DisplaceDriverUnload = TRUE;
307  }
308 
309  if (Driver != NULL) {
310  *Driver = hDriver;
311  }
312 
313 #ifndef __REACTOS__
314  if (FX_TELEMETRY_ENABLED(g_TelemetryProvider, pFxDriverGlobals)) {
315  FxAutoString imageName;
316 
317 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
318  const PWCHAR pVersionStr =
319  FX_MAKE_WSTR(__WDF_MAJOR_VERSION_STRING) L"."
320  FX_MAKE_WSTR(__WDF_MINOR_VERSION_STRING) L"."
321  FX_MAKE_WSTR(__WDF_BUILD_NUMBER) ;
322 #else // USER_MODE
323  const PWCHAR pVersionStr =
324  FX_MAKE_WSTR(__WUDF_MAJOR_VERSION_STRING) L"."
325  FX_MAKE_WSTR(__WUDF_MINOR_VERSION_STRING) L"."
326  FX_MAKE_WSTR(__WUDF_SERVICE_VERSION) ;
327 #endif
328 
329  //
330  // GetImageName can fail if the registry cannot be accessed. This
331  // can happen during system shutdown. Since the image name is only
332  // used for telemetry the failure can be ignored.
333  //
335 
336  WDF_CENSUS_EVT_WRITE_DRIVER_LOAD(g_TelemetryProvider,
338  imageName.m_UnicodeString.Buffer,
339  pVersionStr);
340  }
341 #endif // __REACTOS__
342  }
343  else {
344  if (pDriver != NULL) {
346  }
347 
349  }
350 
351  return status;
352 }
353 
356 NTSTATUS
357 STDCALL
358 WDFEXPORT(WdfDriverRegisterTraceInfo)(
359  __in
361  __in
363  __in
365  __in
367  )
368 {
369  DDI_ENTRY();
370 
375 
377 }
378 
381 NTSTATUS
382 STDCALL
383 WDFEXPORT(WdfDriverRetrieveVersionString)(
384  __in
386  __in
387  WDFDRIVER Driver,
388  __in
389  WDFSTRING String
390  )
391 {
392  DDI_ENTRY();
393 
395  FxDriver* pDriver;
398 
399 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
401  L"Kernel Mode Driver Framework version "
402  FX_MAKE_WSTR(__WDF_MAJOR_VERSION_STRING) L"."
403  FX_MAKE_WSTR(__WDF_MINOR_VERSION_STRING) L"."
404  FX_MAKE_WSTR(__WDF_BUILD_NUMBER) ;
405 
407  L"Kernel Mode Driver Framework (verifier on) version "
408  FX_MAKE_WSTR(__WDF_MAJOR_VERSION_STRING) L"."
409  FX_MAKE_WSTR(__WDF_MINOR_VERSION_STRING) L"."
410  FX_MAKE_WSTR(__WDF_BUILD_NUMBER);
411 #else // USER_MODE
412  const PWCHAR pVersionStr =
413  L"User Mode Driver Framework version "
414  FX_MAKE_WSTR(__WUDF_MAJOR_VERSION_STRING) L"."
415  FX_MAKE_WSTR(__WUDF_MINOR_VERSION_STRING) L"."
416  FX_MAKE_WSTR(__WUDF_SERVICE_VERSION) ;
417 
419  L"User Mode Driver Framework (verifier on) version "
420  FX_MAKE_WSTR(__WUDF_MAJOR_VERSION_STRING) L"."
421  FX_MAKE_WSTR(__WUDF_MINOR_VERSION_STRING) L"."
422  FX_MAKE_WSTR(__WUDF_SERVICE_VERSION);
423 #endif
424 
425  //
426  // Even though it is unused, still convert it to make sure a valid handle is
427  // being passed in.
428  //
430  Driver,
432  (PVOID *)&pDriver,
434 
436 
438  if (!NT_SUCCESS(status)) {
439  return status;
440  }
441 
443  String,
445  (PVOID *)&pString);
446 
447  status = pString->Assign(
449  );
450 
451  return status;
452 }
453 
456 BOOLEAN
457 STDCALL
458 WDFEXPORT(WdfDriverIsVersionAvailable)(
459  __in
461  __in
462  WDFDRIVER Driver,
463  __in
465  )
466 {
467  DDI_ENTRY();
468 
470  FxDriver* pDriver;
473 
474 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
475  major = __WDF_MAJOR_VERSION;
476  minor = __WDF_MINOR_VERSION;
477 #else
478  major = __WUDF_MAJOR_VERSION;
479  minor = __WUDF_MINOR_VERSION;
480 #endif
481 
482  //
483  // Even though it is unused, still convert it to make sure a valid handle is
484  // being passed in.
485  //
487  Driver,
489  (PVOID *)&pDriver,
491 
493 
495  if (!NT_SUCCESS(status)) {
496  return FALSE;
497  }
498 
501 
504  "VersionAvailableParams Size 0x%x, expected 0x%x, %!STATUS!",
506  status);
507 
508  return FALSE;
509  }
510 
511  //
512  // We log at TRACE_LEVEL_INFORMATION so that we know it gets into the IFR at
513  // all times. This will make it easier to debug drivers which fail to load
514  // when a new minor version of WDF is installed b/c they are failing
515  // version checks.
516  //
519  "IsVersionAvailable, current WDF ver major %d, minor %d, caller asking "
520  "about major %d, minor %d", major, minor,
521  VersionAvailableParams->MajorVersion, VersionAvailableParams->MinorVersion);
522 
523  //
524  // Currently we only support one major version per KMDF binary and we support
525  // all minor versions of that major version down to 0x0.
526  //
527  if (VersionAvailableParams->MajorVersion == major &&
528  VersionAvailableParams->MinorVersion <= minor) {
529  return TRUE;
530  }
531 
532  return FALSE;
533 }
534 
535 } // extern "C"
#define DDI_ENTRY()
Definition: fxglobalskm.h:56
return STATUS_NOT_SUPPORTED
VOID RosInitWdf()
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
FxString * pString
__in WDFDRIVER Driver
Definition: fxdriverapi.cpp:54
GLint x0
Definition: linetemp.h:95
_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
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:56
UNREFERENCED_PARAMETER(DriverGlobals)
WDFCASSERT(sizeof(WDF_DRIVER_CONFIG_V1_0)==sizeof(WDF_DRIVER_CONFIG_V1_1))
_Must_inspect_result_ NTSTATUS Initialize(__in PCUNICODE_STRING RegistryPath, __in PWDF_DRIVER_CONFIG Config, __in_opt PWDF_OBJECT_ATTRIBUTES DriverAttributes)
Definition: fxdriver.cpp:334
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR _In_ HANDLE hDriver
Definition: winddi.h:3553
#define TRACINGDRIVER
Definition: dbgtrace.h:68
_Must_inspect_result_ _In_ WDFDRIVER _In_ PWDF_DRIVER_VERSION_AVAILABLE_PARAMS VersionAvailableParams
Definition: wdfdriver.h:436
DriverGlobals
uint16_t * PWCHAR
Definition: typedefs.h:56
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
_Must_inspect_result_ __in MdDriverObject __in PCUNICODE_STRING __in_opt PWDF_OBJECT_ATTRIBUTES DriverAttributes
Definition: fxdriverapi.cpp:86
_Must_inspect_result_ NTSTATUS GetImageName(_In_ PFX_DRIVER_GLOBALS DriverGlobals, _Out_ PUNICODE_STRING ImageName)
PFX_DRIVER_GLOBALS pFxDriverGlobals
Definition: fxdriverapi.cpp:57
const LONG validFlags
#define __out_opt
Definition: dbghelp.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
long LONG
Definition: pedump.c:60
#define WDFEXPORT(a)
Definition: fxmacros.hpp:157
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGDRIVER, "IsVersionAvailable, current WDF ver major %d, minor %d, caller asking " "about major %d, minor %d", major, minor, VersionAvailableParams->MajorVersion, VersionAvailableParams->MinorVersion)
FxDriver * pDriver
Definition: fxdriverapi.cpp:59
FxDriver * Driver
Definition: fxglobals.h:374
unsigned char BOOLEAN
ULONG major
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PFN_WDF_TRACE_CALLBACK _In_ PVOID ControlBlock
Definition: wdfdriver.h:370
#define FX_TELEMETRY_ENABLED(TraceHandle, Globals)
Definition: fxtelemetry.hpp:45
static VOID _InitializeTag(__in PFX_DRIVER_GLOBALS Globals, __in PWDF_DRIVER_CONFIG Config)
Definition: fxdriver.cpp:266
return FALSE
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
PUNICODE_STRING GetRegistryPathUnicodeString(VOID)
Definition: fxdriver.hpp:243
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Driver, FX_TYPE_DRIVER,(PVOID *)&pDriver, &pFxDriverGlobals)
PWDF_DRIVER_GLOBALS WdfDriverGlobals
_Must_inspect_result_ __in WDFDRIVER __in PWDF_DRIVER_VERSION_AVAILABLE_PARAMS VersionAvailableParams
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
#define STDCALL
Definition: wdf.h:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define WDF_CENSUS_EVT_WRITE_DRIVER_LOAD(TraceHandle, Globals, DrvImage, WdfVersion)
Definition: fxtelemetry.hpp:72
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING _In_opt_ PWDF_OBJECT_ATTRIBUTES DriverAttributes
Definition: wdfdriver.h:213
_Must_inspect_result_ NTSTATUS Assign(__in PCWSTR SourceString)
Definition: fxstring.cpp:57
FxInitialize(pFxDriverGlobals, DriverObject, RegistryPath, DriverConfig)
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
WDFDRIVER hDriver
_Must_inspect_result_ __in MdDriverObject __in PCUNICODE_STRING RegistryPath
Definition: fxdriverapi.cpp:86
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ NTSTATUS FxValidateObjectAttributes(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
#define VOID
Definition: acefi.h:82
_Must_inspect_result_ NTSTATUS __inline FxValidateUnicodeString(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PCUNICODE_STRING String)
const PWCHAR pVersionStr
__drv_maxIRQL(PASSIVE_LEVEL) PWSTR STDCALL WDFEXPORT(WdfDriverGetRegistryPath)(__in PWDF_DRIVER_GLOBALS DriverGlobals
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define _Must_inspect_result_
Definition: ms_sal.h:558
_Must_inspect_result_ __in MdDriverObject __in PCUNICODE_STRING __in_opt PWDF_OBJECT_ATTRIBUTES __in PWDF_DRIVER_CONFIG DriverConfig
Definition: fxdriverapi.cpp:86
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
VOID FxDestroy(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: globals.cpp:981
#define FX_MAKE_WSTR(x)
Definition: fxmacros.hpp:264
FxObjectHandleGetPtr(pFxDriverGlobals, String, FX_TYPE_STRING,(PVOID *)&pString)
FxPointerNotNull(pFxDriverGlobals, DriverObject)
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PFN_WDF_TRACE_CALLBACK EvtTraceCallback
Definition: wdfdriver.h:370
#define NULL
Definition: types.h:112
_Must_inspect_result_ __in PDRIVER_OBJECT __in PFN_WDF_TRACE_CALLBACK EvtTraceCallback
EVT_WDF_TRACE_CALLBACK * PFN_WDF_TRACE_CALLBACK
Definition: wdfdriver.h:118
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
_Must_inspect_result_ __in MdDriverObject DriverObject
Definition: fxdriverapi.cpp:86
_Must_inspect_result_ __in WDFDRIVER __in WDFSTRING String
const PWCHAR pVersionStrVerifier
unsigned int ULONG
Definition: retypes.h:1
_Must_inspect_result_ __in PDRIVER_OBJECT __in PFN_WDF_TRACE_CALLBACK __in PVOID ControlBlock
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
UNICODE_STRING m_UnicodeString
static VOID _InitializeDriverName(__in PFX_DRIVER_GLOBALS Globals, __in PCUNICODE_STRING RegistryPath)
Definition: fxdriver.cpp:180
#define __in
Definition: dbghelp.h:35
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
NTSTATUS status
Definition: fxdriverapi.cpp:58
ULONG minor
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ PWDF_DRIVER_CONFIG DriverConfig
Definition: wdfdriver.h:213
#define DO_NOTHING()
Definition: mxgeneral.h:32
Definition: ps.c:97