ReactOS 0.4.16-dev-136-g52192f1
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
8extern "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
33extern "C" {
34//
35// Global triage Info for dbgeng and 0x9F work
36//
37static WDFOBJECT_TRIAGE_INFO _WdfObjectTriageInfo = {0};
38static WDFCONTEXT_TRIAGE_INFO _WdfContextTriageInfo = {0};
39static WDFCONTEXTTYPE_TRIAGE_INFO _WdfContextTypeTriageInfo = {0};
40static WDFQUEUE_TRIAGE_INFO _WdfQueueTriageInfo = {0};
41static WDFIRPQUEUE_TRIAGE_INFO _WdfIrpQueueTriageInfo = {0};
42static WDFREQUEST_TRIAGE_INFO _WdfRequestTriageInfo = {0};
43static WDFDEVICE_TRIAGE_INFO _WdfDeviceTriageInfo = {0};
44static WDFIRP_TRIAGE_INFO _WdfIrpTriageInfo = {0};
45static WDFFWDPROGRESS_TRIAGE_INFO _WdfFwdProgressTriageInfo = {0};
46
47WDF_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
80VOID
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);
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
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
204 VOID
205 )
206{
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
244 )
245{
247
249
251
252 ASSERT(Info != NULL && Info->FuncCount != 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
400Done:
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
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
465VOID
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}
unsigned char BOOLEAN
#define TODO
Definition: SAX2.c:44
LONG NTSTATUS
Definition: precomp.h:26
virtual VOID DeleteObject(VOID)
Definition: fxdriver.hpp:332
Definition: fxirp.hpp:28
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T ContextSize
Definition: fltkernel.h:1444
FX_VERIFY(INTERNAL, CHECK_NOT_NULL(LoaderInterface->pIWudfHost))
PFX_DRIVER_GLOBALS pFxDriverGlobals
PFX_DRIVER_GLOBALS fxDriverGlobals
VOID FxLibraryGlobalsDecommission(VOID)
Definition: globals.cpp:742
_Must_inspect_result_ NTSTATUS FxLibraryGlobalsCommission(VOID)
Definition: globals.cpp:494
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
VOID FxDestroy(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: globals.cpp:981
#define WDF_LIBRARY_COMMISSION
Definition: fxldr.h:110
#define WDF_LIBRARY_UNREGISTER_CLIENT
Definition: fxldr.h:113
#define WDF_LIBRARY_DECOMMISSION
Definition: fxldr.h:111
#define WDF_LIBRARY_REGISTER_CLIENT
Definition: fxldr.h:112
VOID FxFreeDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: globals.cpp:1181
_Must_inspect_result_ PWDF_DRIVER_GLOBALS FxAllocateDriverGlobals(VOID)
Definition: globals.cpp:1052
VOID RegisterTelemetryProvider(VOID)
VOID UnregisterTelemetryProvider(VOID)
__inline BOOLEAN IsFxPerformanceAnalysis(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:250
__inline BOOLEAN IsFxVerifierFunctionTableHooking(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxverifier.h:127
CLIENT_DATA ClientInfo
WDFVERSION WdfVersion
#define __Print(_x_)
#define WDF_ENHANCED_VERIFIER_OPTIONS_VALUE_NAME
#define LITERAL(a)
_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)
static WDFIRPQUEUE_TRIAGE_INFO _WdfIrpQueueTriageInfo
static WDFCONTEXT_TRIAGE_INFO _WdfContextTriageInfo
VOID GetTriageInfo(VOID)
_Must_inspect_result_ NTSTATUS FxLibraryCommonCommission(VOID)
WDF_TRIAGE_INFO g_WdfTriageInfo
static WDFDEVICE_TRIAGE_INFO _WdfDeviceTriageInfo
static WDFCONTEXTTYPE_TRIAGE_INFO _WdfContextTypeTriageInfo
static WDFREQUEST_TRIAGE_INFO _WdfRequestTriageInfo
static WDFOBJECT_TRIAGE_INFO _WdfObjectTriageInfo
_Must_inspect_result_ NTSTATUS FxLibraryCommonUnregisterClient(__in PWDF_BIND_INFO Info, __in PWDF_DRIVER_GLOBALS WdfDriverGlobals)
VOID GetEnhancedVerifierOptions(__in PCLIENT_INFO ClientInfo, __out PULONG Options)
static WDFFWDPROGRESS_TRIAGE_INFO _WdfFwdProgressTriageInfo
static WDFIRP_TRIAGE_INFO _WdfIrpTriageInfo
static WDFQUEUE_TRIAGE_INFO _WdfQueueTriageInfo
#define __assume(x)
Definition: intrin.h:108
#define ASSERT(a)
Definition: mode.c:44
#define KEY_READ
Definition: nt_native.h:1023
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN InternalTracingInitialized
Definition: fxglobals.h:804
FxDriver * Driver
Definition: fxglobals.h:374
ULONG FxEnhancedVerifierOptions
Definition: fxglobals.h:518
ULONG FuncCount
Definition: fxdynamics.h:593
WDFFUNCTIONS Functions
Definition: fxdynamics.h:594
Definition: ps.c:97
VOID TraceUninitialize(VOID)
Definition: tracing.cpp:79
VOID FxIFRStop(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: tracing.cpp:297
_Must_inspect_result_ NTSTATUS FxTraceInitialize(VOID)
Definition: tracing.cpp:47
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Definition: pdh_main.c:94
@ WdfFunctionTableNumEntries_V2_0
Definition: wdf20.h:9
@ WdfFunctionTableNumEntries_V2_15
Definition: wdf215.h:6
VOID(* WDFFUNC)(VOID)
Definition: wdf.h:68
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
PWDF_DRIVER_GLOBALS WdfDriverGlobals
@ WdfFunctionTableNumEntries
Definition: wdffuncenum.h:469
struct _WDF_OBJECT_CONTEXT_TYPE_INFO WDF_OBJECT_CONTEXT_TYPE_INFO