1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxTelemetry.hpp
8 
9 Abstract:
10 
11     This is the header file for core framework (Wdf0100 and Wudfx02000)
12     related telemetry.
13 
14 Author:
15 
16 
17 
18 Environment:
19 
20     Both kernel and user mode
21 
22 Revision History:
23 
24 Notes:
25 
26 --*/
27 
28 #pragma once
29 
30 #include <strsafe.h>
31 #include "fxtelemetrycommon.hpp"
32 
33 #if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
34 #include "fxtelemetrykm.hpp"
35 #else
36 #include "fxtelemetryum.hpp"
37 #endif
38 
39 #if defined(__cplusplus)
40 extern "C" {
41 #endif
42 
43 // TRACELOGGING_DECLARE_PROVIDER(g_TelemetryProvider); __REACTOS__
44 
45 #define FX_TELEMETRY_ENABLED(TraceHandle, Globals)                \
46     (TraceHandle && IsDriverTelemetryContextInitialized(Globals))     \
47 
48 #define WDF_CENSUS_EVT_DATA_COMMON(FxGlobals)                     \
49     TraceLoggingStruct(1, "CensusCommonV1"),                      \
50         TraceLoggingGuid((FxGlobals)->TelemetryContext->DriverSessionGUID, "SessionGUID")
51 
52 //
53 // For events that want to fire once per
54 // session define a bit for use in DoOnceFlagsBitmap
55 //
56 typedef enum _FX_TELEMETRY_DO_ONCE_BITS {
57     DeviceStartEventBit = 0
58 } FX_TELEMETRY_DO_ONCE_BITS;
59 
60 //
61 // Event name:  WdfCensusEvtDrvLoad
62 //
63 // Source:      Mode agnostic (UMDF and KMDF)
64 //
65 // Description: Written when a WDF client or cx calls WdfDriverCreate.
66 //              The event contains information about the driver version,
67 //              verifier options, service name and driver configuration
68 //              to track non-pnp drivers or WDF miniports.
69 //
70 // Frequency:   If FX_TELEMETRY_ENABLED then everytime a driver calls WdfDriverCreate.
71 //
72 #define WDF_CENSUS_EVT_WRITE_DRIVER_LOAD(TraceHandle, Globals, DrvImage, WdfVersion)   \
73             TraceLoggingWrite(TraceHandle,                                             \
74                 "WdfCensusEvtDrvLoad",                                                 \
75                 WDF_TELEMETRY_EVT_KEYWORDS,                                            \
76                 WDF_CENSUS_EVT_DATA_COMMON(Globals),                                   \
77                 TraceLoggingStruct(9, "DriverInfo"                                                                                       ), \
78                     TraceLoggingString((Globals)->Public.DriverName,                                         "DriverService"             ), \
79                     TraceLoggingWideString(DrvImage,                                                         "DriverImage"               ), \
80                     TraceLoggingWideString(WdfVersion,                                                       "WdfVersion"                ), \
81                     TraceLoggingUInt32((Globals)->WdfBindInfo->Version.Major,                                "DriverVersionMajor"        ), \
82                     TraceLoggingUInt32((Globals)->WdfBindInfo->Version.Minor,                                "DriverVersionMinor"        ), \
83                     TraceLoggingBoolean((Globals)->FxVerifierOn,                                             "FxVerifierOn"              ), \
84                     TraceLoggingBoolean(!!((Globals)->Public.DriverFlags & WdfDriverInitNonPnpDriver),       "DriverNonPnP"              ), \
85                     TraceLoggingBoolean(!!((Globals)->Public.DriverFlags & WdfDriverInitNoDispatchOverride), "DriverNoDispatchOverride"  ), \
86                     TraceLoggingUInt32((Globals)->FxEnhancedVerifierOptions,                                 "FxEnhancedVeriferOptions"  )  \
87                 );
88 
89 #define MIN_HOURS_BEFORE_NEXT_LOG  24
90 #define BASE_10 (10)
91 
92 #define WDF_LAST_TELEMETRY_LOG_TIME_VALUE L"TimeOfLastTelemetryLog"
93 #define WDF_DRIVER_IMAGE_NAME_VALUE L"ImagePath"
94 
95 //
96 // bit-flags for tracking hardware info for device start telemetry event
97 //
98 enum FxDeviceInfoFlags : USHORT {
99     DeviceInfoLineBasedLevelTriggeredInterrupt =   0x1,
100     DeviceInfoLineBasedEdgeTriggeredInterrupt  =   0x2,
101     DeviceInfoMsiXOrSingleMsi22Interrupt       =   0x4,
102     DeviceInfoMsi22MultiMessageInterrupt       =   0x8,
103     DeviceInfoPassiveLevelInterrupt            =  0x10,
104     DeviceInfoDmaBusMaster                     =  0x20,
105     DeviceInfoDmaSystem                        =  0x40,
106     DeviceInfoDmaSystemDuplex                  =  0x80,
107     DeviceInfoHasStaticChildren                = 0x100,
108     DeviceInfoHasDynamicChildren               = 0x200,
109     DeviceInfoIsUsingDriverWppRecorder         = 0x400
110 };
111 
112 //
113 // wdf version strig example "01.011"
114 //
115 #define WDF_VERSION_STRING_SIZE_INCLUDING_SEPARATOR_CCH   10
116 
117 BOOLEAN
118 __inline
IsDeviceInfoFlagSet(_In_ USHORT DeviceInfo,_In_ FxDeviceInfoFlags Flag)119 IsDeviceInfoFlagSet(
120     _In_ USHORT DeviceInfo,
121     _In_ FxDeviceInfoFlags Flag
122     )
123 {
124     return FLAG_TO_BOOL(DeviceInfo, Flag);
125 }
126 
127 VOID
128 AllocAndInitializeTelemetryContext(
129     _In_ PFX_TELEMETRY_CONTEXT* TelemetryContext
130     );
131 
132 __inline
133 BOOLEAN
IsDriverTelemetryContextInitialized(_In_ PFX_DRIVER_GLOBALS FxDrvGlobals)134 IsDriverTelemetryContextInitialized(
135 _In_ PFX_DRIVER_GLOBALS FxDrvGlobals
136 )
137 {
138     ASSERT(FxDrvGlobals);
139     return (NULL != FxDrvGlobals->TelemetryContext);
140 }
141 
142 VOID
143 RegisterTelemetryProvider(
144     VOID
145     );
146 
147 VOID
148 UnregisterTelemetryProvider(
149     VOID
150     );
151 
152 VOID
153 LogDeviceStartTelemetryEvent(
154     _In_ PFX_DRIVER_GLOBALS Globals,
155     _In_opt_ FxDevice* Fdo
156     );
157 
158 VOID
159 LogDriverInfoStream(
160     _In_ PFX_DRIVER_GLOBALS Globals,
161     _In_opt_ FxDevice* Fdo
162     );
163 
164 _Must_inspect_result_
165 NTSTATUS
166 GetImageName(
167     _In_ PFX_DRIVER_GLOBALS DriverGlobals,
168     _Out_ PUNICODE_STRING ImageName
169     );
170 
171 VOID
172 __inline
BuildStringFromPartialInfo(_In_ PKEY_VALUE_PARTIAL_INFORMATION Info,_Out_ PUNICODE_STRING String)173 BuildStringFromPartialInfo(
174     _In_ PKEY_VALUE_PARTIAL_INFORMATION Info,
175     _Out_ PUNICODE_STRING String
176     )
177 {
178     String->Buffer = (PWCHAR) &Info->Data[0];
179     String->MaximumLength = (USHORT) Info->DataLength;
180     String->Length = String->MaximumLength - sizeof(UNICODE_NULL);
181 
182     //
183     // ensure string is null terminated
184     //
185     String->Buffer[String->Length/sizeof(WCHAR)] = UNICODE_NULL;
186 }
187 
188 VOID
189 GetNameFromPath(
190     _In_ PCUNICODE_STRING Path,
191     _Out_ PUNICODE_STRING Name
192     );
193 
194 #if defined(__cplusplus)
195 }
196 #endif
197 
198