ReactOS  0.4.15-dev-2720-g5ee0925
fxlibrarycommon.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) Microsoft. All rights reserved.
3 //
4 #include <ntverp.h>
5 #include <strsafe.h>
6 #include <driverspecs.h>
7 
8 extern "C" {
9 #include "mx.h"
10 }
11 #include "fxmin.hpp"
12 #include <fxldrUm.h>
13 
14 #include <wdfcxbase.h>
15 #include "wdf20.h"
16 #include "wdf215.h"
17 
18 //
19 // This will cause inclusion of VfWdfFunctions table implementation from header
20 //
21 #define VF_FX_DYNAMICS_GENERATE_TABLE 1
22 
23 
24 
25 
26 
27 #include "..\version\FxDynamics.h"
28 #include "..\version\vffxdynamics.h"
29 #include "FxLibraryCommon.h"
30 
31 #include "FxTelemetry.hpp"
32 
33 extern "C" {
34 //
35 // Global triage Info for dbgeng and 0x9F work
36 //
37 static WDFOBJECT_TRIAGE_INFO _WdfObjectTriageInfo = {0};
38 static WDFCONTEXT_TRIAGE_INFO _WdfContextTriageInfo = {0};
39 static WDFCONTEXTTYPE_TRIAGE_INFO _WdfContextTypeTriageInfo = {0};
40 static WDFQUEUE_TRIAGE_INFO _WdfQueueTriageInfo = {0};
41 static WDFIRPQUEUE_TRIAGE_INFO _WdfIrpQueueTriageInfo = {0};
42 static WDFREQUEST_TRIAGE_INFO _WdfRequestTriageInfo = {0};
43 static WDFDEVICE_TRIAGE_INFO _WdfDeviceTriageInfo = {0};
44 static WDFIRP_TRIAGE_INFO _WdfIrpTriageInfo = {0};
45 static WDFFWDPROGRESS_TRIAGE_INFO _WdfFwdProgressTriageInfo = {0};
46 
47 WDF_TRIAGE_INFO g_WdfTriageInfo = {
48  //
49  // UMDF Version.
50  //
51  __WUDF_MAJOR_VERSION,
52  __WUDF_MINOR_VERSION,
53 
54  //
55  // Table Version.
56  //
57  WDF_01_TRIAGE_INFO_MAJOR_VERSION,
58  WDF_01_TRIAGE_INFO_MINOR_VERSION,
59 
60  //
61  // Reserved ptr (set to NULL).
62  //
63  NULL,
64 
65  //
66  // WDF objects triage info.
67  //
77 };
78 } // extern "C"
79 
80 VOID
82  VOID
83  )
84 {
85  // Object
86  _WdfObjectTriageInfo.RawObjectSize = sizeof(FxObject);
87  _WdfObjectTriageInfo.ObjectType = FIELD_OFFSET(FxObject, m_Type);
88  _WdfObjectTriageInfo.TotalObjectSize = FIELD_OFFSET(FxObject, m_ObjectSize);
89  _WdfObjectTriageInfo.ChildListHead = FIELD_OFFSET(FxObject, m_ChildListHead);
90  _WdfObjectTriageInfo.ChildEntry = FIELD_OFFSET(FxObject, m_ChildEntry);
91  _WdfObjectTriageInfo.Globals = FIELD_OFFSET(FxObject, m_Globals);
92  _WdfObjectTriageInfo.ParentObject = FIELD_OFFSET(FxObject, m_ParentObject);
93 
94  // Context Triage Info
95  _WdfContextTriageInfo.HeaderSize = sizeof(FxContextHeader);
96  _WdfContextTriageInfo.NextHeader = FIELD_OFFSET(FxContextHeader, NextHeader);
98  _WdfContextTriageInfo.TypeInfoPtr = FIELD_OFFSET(FxContextHeader, ContextTypeInfo);
100 
101  // Context type Triage info
105 
106  // WdfRequest Queue
107  _WdfQueueTriageInfo.QueueSize = sizeof(FxIoQueue);
108  _WdfQueueTriageInfo.IrpQueue1 = FIELD_OFFSET(FxIoQueue, m_Queue);
109  _WdfQueueTriageInfo.IrpQueue2 = FIELD_OFFSET(FxIoQueue, m_DriverCancelable);
110  _WdfQueueTriageInfo.RequestList1 = FIELD_OFFSET(FxIoQueue, m_Cancelled);
111  _WdfQueueTriageInfo.RequestList2 = FIELD_OFFSET(FxIoQueue, m_CanceledOnQueueList);
112  _WdfQueueTriageInfo.FwdProgressContext = FIELD_OFFSET(FxIoQueue, m_FwdProgContext);
113  _WdfQueueTriageInfo.PkgIo = FIELD_OFFSET(FxIoQueue, m_PkgIo);
114 
115  // Forward Progress
116  _WdfFwdProgressTriageInfo.ReservedRequestList =
117  FIELD_OFFSET(FXIO_FORWARD_PROGRESS_CONTEXT, m_ReservedRequestList);
118  _WdfFwdProgressTriageInfo.ReservedRequestInUseList =
119  FIELD_OFFSET(FXIO_FORWARD_PROGRESS_CONTEXT, m_ReservedRequestInUseList);
120  _WdfFwdProgressTriageInfo.PendedIrpList =
122 
123  // Irp Queue
124  _WdfIrpQueueTriageInfo.IrpQueueSize = sizeof(FxIrpQueue);
125  _WdfIrpQueueTriageInfo.IrpListHeader = FIELD_OFFSET(FxIrpQueue, m_Queue);
126 
127 
128 
129 
130 
131 
132 
133 
134 
135  _WdfIrpQueueTriageInfo.IrpListEntry = 0;
136  _WdfIrpQueueTriageInfo.IrpContext = 0;
137 
138  // WdfRequest
139  _WdfRequestTriageInfo.RequestSize = sizeof(FxRequest);
140  _WdfRequestTriageInfo.CsqContext = FIELD_OFFSET(FxRequest, m_CsqContext);
142  _WdfRequestTriageInfo.ListEntryQueueOwned =
143  FIELD_OFFSET(FxRequest, m_OwnerListEntry);
144  _WdfRequestTriageInfo.ListEntryQueueOwned2 =
145  FIELD_OFFSET(FxRequest, m_OwnerListEntry2);
146  _WdfRequestTriageInfo.RequestListEntry =
147  FIELD_OFFSET(FxRequest, m_ListEntry);
148  _WdfRequestTriageInfo.FwdProgressList =
149  FIELD_OFFSET(FxRequest, m_ForwardProgressList);
150 
151  // WdfDevice
152  _WdfDeviceTriageInfo.DeviceInitSize = sizeof(WDFDEVICE_INIT);
153  _WdfDeviceTriageInfo.DeviceDriver = FIELD_OFFSET(FxDevice, m_Driver);
154 
155  // FxIrp
156  _WdfIrpTriageInfo.FxIrpSize = sizeof(FxIrp);
157  _WdfIrpTriageInfo.IrpPtr = FIELD_OFFSET(FxIrp, m_Irp);
158 }
159 
160 NTSTATUS
162  VOID
163  )
164 {
166 
168 
169  //
170  // Commission this version's DLL globals.
171  //
173  if (!NT_SUCCESS(status)) {
174  __Print(("FxLibraryGlobalsCommission failed %X\n", status));
175  return status;
176  }
177 
178  //
179  // register for ETW tracing.
180  //
182 
183  //
184  // Initialize internal WPP tracing.
185  //
187  if (NT_SUCCESS(status)) {
189  }
190  else {
191  __Print(("Failed to initialize tracing for WDF\n"));
192 
193  //
194  // Failure to initialize is not critical enough to fail driver load.
195  //
197  }
198 
199  return status;
200 }
201 
202 NTSTATUS
204  VOID
205  )
206 {
207  __Print((LITERAL(WDF_LIBRARY_DECOMMISSION) ": enter\n"));
208 
209  //
210  // Uninitialize WPP tracing.
211  //
215  }
216 
217  //
218  // Unregister telemetry provider.
219  //
221 
222  EventUnregisterMicrosoft_Windows_DriverFrameworks_UserMode_Performance();
223 
224  //
225  // Decommission this version's DLL globals.
226  //
228 
229  //
230  // Note: This is the absolute last action from WDF library (dynamic or static).
231  // The image is likely to be deleted after returning.
232  //
234 
235  return STATUS_SUCCESS;
236 }
237 
238 
239 NTSTATUS
244  )
245 {
247 
249 
251 
252  ASSERT(Info != NULL && Info->FuncCount != 0);
253  ASSERT(WdfDriverGlobals != 0);
254 
255  if (Info == NULL || WdfDriverGlobals == NULL || Info->FuncTable == NULL) {
257  ": NULL parameter -- %s\n",
258  (Info == NULL) ? "PWDF_BIND_INFO" :
259  (WdfDriverGlobals == NULL) ? "PWDF_DRIVER_GLOBALS *" :
260  (Info->FuncTable == NULL) ? "PWDF_BIND_INFO->FuncTable" :
261  "unknown" ));
262  goto Done;
263  }
264 
266 
267  ASSERT(Info->FuncCount <= WdfVersion.FuncCount);
268 
269  //
270  // WdfVersion.Count is initialized in FxDynamics.h and is never changed.
271  // Prefast is unable to make that determination.
272  //
273  __assume(WdfVersion.FuncCount == sizeof(WDFFUNCTIONS)/sizeof(PVOID));
274 
275  if (Info->FuncCount > WdfVersion.FuncCount) {
277  ": version mismatch detected in function table count: client"
278  "has 0x%x, library has 0x%x\n",
279  Info->FuncCount, WdfVersion.FuncCount));
280  goto Done;
281  }
282 
283  if (Info->FuncCount <= WdfFunctionTableNumEntries_V2_15) {
284 
285  switch (Info->FuncCount) {
286 
289  break;
290 
291  default:
293  ": Function table count 0x%x doesn't match any previously "
294  "released framework version table size\n",
295  Info->FuncCount));
296  goto Done;
297  }
298  }
299  else {
300  //
301  // Client version is same as framework version. Make
302  // sure table count is exact.
303  //
304  // Note that in order for build-to-build upgrade to work, the following
305  // check should be commented out during active development.
306  //
307  // DO CHANGE it to a real failure towards the tail end of release to
308  // prevent cases where a driver sneaks out into public after being built
309  // with a non-RTM version of WDF and has a function count less than the
310  // final count. An HCK test has been added to ensure such drivers are
311  // caught early. This check is an additional prevention.
312  //
313  if (Info->FuncCount != WdfFunctionTableNumEntries) {
314  __Print(("Framework function table size (%d) doesn't match "
315  "with client (%d). Rebuild the client driver.",
316  WdfFunctionTableNumEntries, Info->FuncCount));
317 
318  ASSERT(FALSE);
319  goto Done;
320  }
321  }
322 
323  //
324  // Allocate an new FxDriverGlobals area for this driver.
325  //
327 
328  if (*WdfDriverGlobals) {
329  BOOLEAN isFunctinTableHookingOn = FALSE;
330  BOOLEAN isPerformanceAnalysisOn = FALSE;
332  //
333  // Check the registry to see if Enhanced verifier is on for this driver.
334  // if registry read fails, options value remains unchanged.
335  // store enhanced verifier options in driver globals
336  //
339  isFunctinTableHookingOn = IsFxVerifierFunctionTableHooking(fxDriverGlobals);
340  isPerformanceAnalysisOn = IsFxPerformanceAnalysis(fxDriverGlobals);
341 
342  //
343  // Set-up the function table. Enhanced verifier and Performance analysis is off by default.
344  //
345  if (isFunctinTableHookingOn == FALSE && isPerformanceAnalysisOn == FALSE) {
346  //
347  // Set-up the function table
348  //
349  // Starting in 2.15 we reference a copy of the DDI table in WDF01000,
350  // prior to that we copy the entire table to local memory.
351  //
352  if (Info->FuncCount <= WdfFunctionTableNumEntries_V2_0) {
353  RtlCopyMemory( Info->FuncTable,
355  Info->FuncCount * sizeof(PVOID) );
356  }
357  else {
358  //
359  // FuncTable arrives with a ptr to &WdfFunctions, so we update
360  // what WdfFunctions points to
361  //
362  *((WDFFUNC**) Info->FuncTable) = (WDFFUNC*) &WdfVersion.Functions;
363  }
364  }
365  else {
367  ": Enhanced Verification is ON \n"));
368 
369  if (Microsoft_Windows_DriverFrameworks_UserMode_PerformanceHandle == NULL)
370  {
371  EventRegisterMicrosoft_Windows_DriverFrameworks_UserMode_Performance();
372  }
373 
374  //
375  // Enhanced verification is on. Return verifier function table
376  //
377  // Starting in 1.15 we reference a copy of the DDI table in WDF01000,
378  // prior to that we copy the entire table to local memory.
379  //
380  if (Info->FuncCount <= WdfFunctionTableNumEntries_V2_0) {
381  RtlCopyMemory( Info->FuncTable,
382  &VfWdfVersion.Functions,
383  Info->FuncCount * sizeof(PVOID) );
384  }
385  else {
386  //
387  // FuncTable arrives with a ptr to &WdfFunctions, so we update
388  // what WdfFunctions points to.
389  //
390  *((WDFFUNC**) Info->FuncTable) = (WDFFUNC*) &VfWdfVersion.Functions;
391  }
392  }
393 
395 
397  ": WdfFunctions %p\n", Info->FuncTable));
398  }
399 
400 Done:
402  ": exit: status %X\n", status));
403 
404  if (!NT_SUCCESS(status)) {
405  FX_VERIFY(DRIVER(BadArgument, TODO),
406  TRAPMSG("Version mismatch detected in function table count. Recompile"
407  " driver with correct headers"));
408  }
409 
410  return status;
411 }
412 
413 NTSTATUS
417  )
418 {
420 
422 
423  ASSERT(Info != NULL);
425 
426  if (Info != NULL && WdfDriverGlobals != NULL) {
428 
430 
432 
433  //
434  // Destroy this FxDriver instance, if its still indicated.
435  //
436  if (pFxDriverGlobals->Driver != NULL) {
437  //
438  // Association support, we are a root with no parent
439  //
441 
443  }
444 
445  //
446  // Stop IFR logging
447  //
449 
450  //
451  // This will free the client's FxDriverGlobals area
452  //
454  }
455  else {
457  }
458 
460  ": exit: status %X\n", status));
461 
462  return status;
463 }
464 
465 VOID
469  )
470 {
472  ULONG value;
473  FxAutoRegKey hWdf;
475 
476  *Options = 0;
477  if (ClientInfo == NULL ||
478  ClientInfo->Size != sizeof(CLIENT_INFO) ||
479  ClientInfo->RegistryPath == NULL ||
480  ClientInfo->RegistryPath->Length == 0 ||
481  ClientInfo->RegistryPath->Buffer == NULL ||
482  Options == NULL) {
483 
485  ": Invalid ClientInfo received from wudfldr \n"));
486  return;
487  }
488 
489  status = FxRegKey::_OpenKey(NULL,
490  ClientInfo->RegistryPath,
491  &hWdf.m_Key,
492  KEY_READ);
493  if (!NT_SUCCESS(status)) {
494  return;
495  }
496 
497  status = FxRegKey::_QueryULong(
498  hWdf.m_Key, &valueName, &value);
499 
500  //
501  // Examine key values and set Options only on success.
502  //
503  if (NT_SUCCESS(status)) {
504  if (value) {
505  *Options = value;
506  }
507  }
508 }
Definition: pdh_main.c:93
BOOLEAN InternalTracingInitialized
Definition: fxglobals.h:804
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _WDFFUNCTIONS WDFFUNCTIONS
LONG NTSTATUS
Definition: precomp.h:26
VOID FxLibraryGlobalsDecommission(VOID)
Definition: globals.cpp:742
Definition: fxirp.hpp:28
static WDFIRP_TRIAGE_INFO _WdfIrpTriageInfo
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T ContextSize
Definition: fltkernel.h:1444
static WDFFWDPROGRESS_TRIAGE_INFO _WdfFwdProgressTriageInfo
VOID GetTriageInfo(VOID)
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
CLIENT_DATA ClientInfo
WDFFUNCTIONS Functions
Definition: fxdynamics.h:594
#define WDF_LIBRARY_UNREGISTER_CLIENT
Definition: fxldr.h:113
#define TODO
Definition: SAX2.c:49
#define FALSE
Definition: types.h:117
VOID FxFreeDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: globals.cpp:1181
FxDriver * Driver
Definition: fxglobals.h:374
ULONG FxEnhancedVerifierOptions
Definition: fxglobals.h:518
unsigned char BOOLEAN
static WDFQUEUE_TRIAGE_INFO _WdfQueueTriageInfo
VOID GetEnhancedVerifierOptions(__in PCLIENT_INFO ClientInfo, __out PULONG Options)
static WDFREQUEST_TRIAGE_INFO _WdfRequestTriageInfo
WDF_TRIAGE_INFO g_WdfTriageInfo
struct _WDF_OBJECT_CONTEXT_TYPE_INFO WDF_OBJECT_CONTEXT_TYPE_INFO
#define WDF_LIBRARY_COMMISSION
Definition: fxldr.h:110
__inline BOOLEAN IsFxVerifierFunctionTableHooking(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:127
#define LITERAL(a)
VOID(* WDFFUNC)(VOID)
Definition: wdf.h:68
PWDF_DRIVER_GLOBALS WdfDriverGlobals
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3531
PFX_DRIVER_GLOBALS pFxDriverGlobals
FX_VERIFY(INTERNAL, CHECK_NOT_NULL(LoaderInterface->pIWudfHost))
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
virtual VOID DeleteObject(VOID)
Definition: fxdriver.hpp:332
#define WDF_LIBRARY_DECOMMISSION
Definition: fxldr.h:111
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ NTSTATUS FxTraceInitialize(VOID)
Definition: tracing.cpp:47
_Must_inspect_result_ NTSTATUS FxLibraryGlobalsCommission(VOID)
Definition: globals.cpp:494
GLsizei const GLfloat * value
Definition: glext.h:6069
VOID FxIFRStop(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: tracing.cpp:297
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
_Must_inspect_result_ PWDF_DRIVER_GLOBALS FxAllocateDriverGlobals(VOID)
Definition: globals.cpp:1052
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
VOID UnregisterTelemetryProvider(VOID)
static WDFCONTEXT_TRIAGE_INFO _WdfContextTriageInfo
VOID FxDestroy(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: globals.cpp:981
static WDFDEVICE_TRIAGE_INFO _WdfDeviceTriageInfo
_Must_inspect_result_ NTSTATUS FxLibraryCommonRegisterClient(__inout PWDF_BIND_INFO Info, __deref_out PWDF_DRIVER_GLOBALS *WdfDriverGlobals, __in_opt PCLIENT_INFO ClientInfo)
_Must_inspect_result_ NTSTATUS FxLibraryCommonDecommission(VOID)
PFX_DRIVER_GLOBALS fxDriverGlobals
#define WDF_ENHANCED_VERIFIER_OPTIONS_VALUE_NAME
static WDFIRPQUEUE_TRIAGE_INFO _WdfIrpQueueTriageInfo
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_Must_inspect_result_ NTSTATUS FxLibraryCommonUnregisterClient(__in PWDF_BIND_INFO Info, __in PWDF_DRIVER_GLOBALS WdfDriverGlobals)
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
static WDFCONTEXTTYPE_TRIAGE_INFO _WdfContextTypeTriageInfo
unsigned int ULONG
Definition: retypes.h:1
VOID TraceUninitialize(VOID)
Definition: tracing.cpp:79
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
static WDFOBJECT_TRIAGE_INFO _WdfObjectTriageInfo
#define STATUS_SUCCESS
Definition: shellext.h:65
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
_Must_inspect_result_ NTSTATUS FxLibraryCommonCommission(VOID)
static SERVICE_STATUS status
Definition: service.c:31
WDFVERSION WdfVersion
ULONG FuncCount
Definition: fxdynamics.h:593
VOID RegisterTelemetryProvider(VOID)
#define WDF_LIBRARY_REGISTER_CLIENT
Definition: fxldr.h:112
#define __Print(_x_)
__inline BOOLEAN IsFxPerformanceAnalysis(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:250
Definition: ps.c:97