ReactOS  0.4.15-dev-3177-gd6a0299
fxtelemetryum.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxTelemetryUm.cpp
8 
9 Abstract:
10 
11  This module implements a telemetry methods.
12 
13 Author:
14 
15 
16 
17 Environment:
18 
19  User mode only
20 
21 Revision History:
22 
23 Notes:
24 
25 --*/
26 
27 #include "fxsupportpch.hpp"
28 #include "DriverFrameworks-UserMode-UmEvents.h"
29 #include "FxldrUm.h"
30 #include <winmeta.h>
31 #include <TraceLoggingProvider.h>
32 #include <telemetry\MicrosoftTelemetry.h>
33 #include <rpc.h>
34 #include <rpcndr.h>
35 
36 extern "C" {
37 #if defined(EVENT_TRACING)
38 #include "FxTelemetryUm.tmh"
39 #endif
40 }
41 
42 /* 8ad60765-a021-4494-8594-9346970cf50f */
43 TRACELOGGING_DEFINE_PROVIDER(g_TelemetryProvider,
45  (0x8ad60765, 0xa021, 0x4494, 0x85, 0x94, 0x93, 0x46, 0x97, 0x0c, 0xf5, 0x0f),
46  TraceLoggingOptionMicrosoftTelemetry());
47 
48 VOID
50  _In_ PFX_TELEMETRY_CONTEXT* TelemetryContext
51  )
52 {
55 
57  sizeof(FX_TELEMETRY_CONTEXT),
58  FX_TAG);
59  if (NULL == context) {
60  goto exit;
61  }
62 
63  status = UuidCreate(&(context->DriverSessionGUID));
64  if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) {
66  context = NULL;
67  goto exit;
68  }
69 
70  context->DoOnceFlagsBitmap = 0;
71 exit:
72  *TelemetryContext = context;
73 }
74 
75 VOID
77  VOID
78  )
79 {
80  EventRegisterMicrosoft_Windows_DriverFrameworks_UserMode();
81 
82  TraceLoggingRegister(g_TelemetryProvider);
83 }
84 
85 VOID
87  VOID
88  )
89 {
90  EventUnregisterMicrosoft_Windows_DriverFrameworks_UserMode();
91 
92  TraceLoggingUnregister(g_TelemetryProvider);
93 }
94 
95 VOID
99  )
100 {
101  // If provider is not enabled we're done.
102  if (FALSE == FX_TELEMETRY_ENABLED(g_TelemetryProvider, Globals)) {
103  return;
104  }
105 
106  //
107  // If we already fired an event during PnP start we are done. This avoids
108  // repeatedly firing events during PnP rebalance.
109  //
111  &Globals->TelemetryContext->DoOnceFlagsBitmap,
112  DeviceStartEventBit) == 1) {
113  return;
114  }
115 
116  //
117  // log the DriverInfo stream.
118  //
120 }
121 
122 VOID
125  _In_ FxDevice* Fdo
126  )
127 {
129  PWCHAR str = NULL;
130  UFxTelemetryDriverInfo driverInfo = {0};
131  LPCWSTR hardwareIds = NULL;
132  LPCWSTR setupClass = NULL;
133  LPCWSTR busEnum = NULL;
134  LPCWSTR manufacturer = NULL;
135  UMDF_DRIVER_REGSITRY_INFO devRegInfo = {0};
136  PCWSTR groupId = NULL;
137  IWudfDeviceStack* devStack = NULL;
138 
139  if (Fdo == NULL) {
140  //
141  // Telemetry events are logged during DriverEntry as well to capture non-pnp
142  // and class extension (which are non-pnp drivers) driver info. Although
143  // current UMDF datapoint doesn't have a separate flag for non-pnp driver,
144  // we still want to log the driver name and its properies if available.
145  //
146  devStack = DriverGlobals->Driver->GetDriverObject()->WudfDevStack;
147  if (devStack != NULL) {
148  devStack->GetPdoProperties(&hardwareIds,
149  &setupClass,
150  &busEnum,
151  &manufacturer);
152  }
153  }
154  else {
155  devStack = Fdo->GetDeviceStack();
156  devStack->GetPdoProperties(&hardwareIds,
157  &setupClass,
158  &busEnum,
159  &manufacturer);
160 
161  Fdo->RetrieveDeviceInfoRegistrySettings(&groupId, &devRegInfo);
162  }
163 
164  //
165  // Log Driver info
166  //
167  if (Fdo != NULL) {
168  GetDriverInfo(Fdo, &devRegInfo, &driverInfo);
169  }
170 
171  UMDF_CENSUS_EVT_WRITE_DEVICE_START(g_TelemetryProvider,
173  driverInfo,
174  setupClass,
175  busEnum,
176  hardwareIds,
177  manufacturer);
178 
179  if (groupId != NULL) {
180  delete [] groupId;
181  groupId = NULL;
182  }
183 }
184 
185 VOID
187  _In_ FxDevice* Fdo,
190  )
191 {
192  FxPkgPnp* pnpPkg;
193  USHORT devInfo = 0;
194  WDF_DEVICE_IO_TYPE readWritePreference;
195  WDF_DEVICE_IO_TYPE ioControlPreference;
196  UMDF_DRIVER_REGSITRY_INFO devRegInfo = {0};
197  PWSTR groupId = NULL;
198 
199  pnpPkg = (FxPkgPnp*)Fdo->GetFdoPkg();
200  devInfo = Fdo->GetDeviceTelemetryInfoFlags();
201  Fdo->GetDeviceStackIoType(&readWritePreference, &ioControlPreference);
202 
203  DriverInfo->bitmap.IsFilter = Fdo->IsFilter();
204  DriverInfo->bitmap.IsPowerPolicyOwner = pnpPkg->IsPowerPolicyOwner();
205  DriverInfo->bitmap.IsS0IdleWakeFromS0Enabled = pnpPkg->IsS0IdleWakeFromS0Enabled();
206  DriverInfo->bitmap.IsS0IdleUsbSSEnabled = pnpPkg->IsS0IdleUsbSSEnabled();
207  DriverInfo->bitmap.IsS0IdleSystemManaged = pnpPkg->IsS0IdleSystemManaged();
208  DriverInfo->bitmap.IsSxWakeEnabled = pnpPkg->IsSxWakeEnabled();
209  DriverInfo->bitmap.IsUsingLevelTriggeredLineInterrupt = IsDeviceInfoFlagSet(devInfo, DeviceInfoLineBasedLevelTriggeredInterrupt);
210  DriverInfo->bitmap.IsUsingEdgeTriggeredLineInterrupt = IsDeviceInfoFlagSet(devInfo, DeviceInfoLineBasedEdgeTriggeredInterrupt);
211  DriverInfo->bitmap.IsUsingMsiXOrSingleMsi22Interrupt = IsDeviceInfoFlagSet(devInfo, DeviceInfoMsiXOrSingleMsi22Interrupt);
212  DriverInfo->bitmap.IsUsingMsi22MultiMessageInterrupt = IsDeviceInfoFlagSet(devInfo, DeviceInfoMsi22MultiMessageInterrupt);
213  DriverInfo->bitmap.IsUsingMultipleInterrupt = pnpPkg->HasMultipleInterrupts();
214  DriverInfo->bitmap.IsDirectHardwareAccessAllowed = Fdo->IsDirectHardwareAccessAllowed();
215  DriverInfo->bitmap.IsUsingUserModemappingAccessMode = Fdo->AreRegistersMappedToUsermode();
216  DriverInfo->bitmap.IsKernelModeClientAllowed = RegInfo->IsKernelModeClientAllowed;
217  DriverInfo->bitmap.IsNullFileObjectAllowed = RegInfo->IsNullFileObjectAllowed;
218  DriverInfo->bitmap.IsPoolingDisabled = RegInfo->IsHostProcessSharingDisabled;
219  DriverInfo->bitmap.IsMethodNeitherActionCopy = RegInfo->IsMethodNeitherActionCopy;
220  DriverInfo->bitmap.IsUsingDirectIoForReadWrite = (readWritePreference == WdfDeviceIoDirect);
221  DriverInfo->bitmap.IsUsingDirectIoForIoctl = (ioControlPreference == WdfDeviceIoDirect);
222  DriverInfo->bitmap.IsUsingDriverWppRecorder = Fdo->GetDriver()->IsDriverObjectFlagSet(DriverObjectUmFlagsLoggingEnabled);
223 
224  return;
225 }
226 
228 NTSTATUS
230  _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
232  )
233 /*++
234 
235 Routine Description:
236  Retrieve the ImageName value from the named Service registry key.
237 
238  Caller is responsible for freeing the buffer allocated in ImageName::Buffer.
239 
240 Arguments:
241  DriverGlobals - pointer to FX_DRIVER_GLOBALS
242 
243  ImageeName - Pointer to a UNICODE_STRING which will receive the image name
244  upon a return value of NT_SUCCESS()
245 
246 Return Value:
247  NTSTATUS
248 
249 --*/
250 {
253  DECLARE_CONST_UNICODE_STRING(valueName, L"ImagePath");
254  UNICODE_STRING imagePath = {0};
255  UNICODE_STRING imageName = {0};
257  USHORT size;
258  ULONG length, type;
260 
261  type = REG_SZ;
262  length = 0;
263 
264  ASSERT(ImageName != NULL);
266 
267  //
268  // Open driver's Service base key
269  //
270  status = FxRegKey::_OpenKey(NULL,
271  FxDriverGlobals->Driver->GetRegistryPathUnicodeString(),
272  &hKey.m_Key,
273  KEY_READ);
274  if (!NT_SUCCESS(status)) {
276  "Unable to open driver's service key, %!STATUS!", status);
277  return status;
278  }
279 
280  //
281  // Find out how big a buffer we need to allocate if the value is present
282  //
283  status = FxRegKey::_QueryValue(FxDriverGlobals,
284  hKey.m_Key,
285  &valueName,
286  length,
287  NULL,
288  &length,
289  &type);
290 
291  //
292  // We expect the list to be bigger then a standard partial, so if it is
293  // not, just bail now.
294  //
296  return STATUS_UNSUCCESSFUL;
297  }
298 
299  //
300  // Pool can be paged b/c we are running at PASSIVE_LEVEL and we are going
301  // to free it at the end of this function.
302  //
303  dataBuffer = FxPoolAllocate(FxDriverGlobals, PagedPool, length);
304  if (dataBuffer == NULL) {
307  "Failed to allocate memory for image path string, %!STATUS!",
308  status);
309  return status;
310  }
311 
312  //
313  // Requery now that we have a big enough buffer
314  //
315  status = FxRegKey::_QueryValue(FxDriverGlobals,
316  hKey.m_Key,
317  &valueName,
318  length,
319  dataBuffer,
320  &length,
321  &type);
322  if (!NT_SUCCESS(status)) {
324  "Failed to get Image name from service key, %!STATUS!",
325  status);
326  goto cleanUp;
327  }
328 
329  //
330  // Verify that the data from the registry is a valid string.
331  //
332  if (type != REG_SZ && type != REG_EXPAND_SZ) {
334  }
335 
336  if (length == 0 || length > USHORT_MAX) {
338  }
339 
340  //
341  // string must be NULL-terminated
342  //
344  if (str[(length/sizeof(WCHAR)) - 1] != UNICODE_NULL) {
347  "ERROR: string not terminated with NULL, %!status!\n",
348  status);
349  goto cleanUp;
350  }
351 
352  RtlInitUnicodeString(&imagePath, (PCWSTR) dataBuffer);
353 
354  //
355  // Now read the "ImagePath" and extract just the driver filename as a new
356  // unicode string.
357  //
358  GetNameFromPath(&imagePath, &imageName);
359 
360  if (imageName.Length == 0x0) {
363  "ERROR: GetNameFromPath could not find a name, %!status!\n",
364  status);
365  goto cleanUp;
366  }
367 
368  //
369  // Check for interger overflow for length before we allocate memory
370  // size = path->Length + sizeof(UNICODE_NULL);
371  // len is used below to compute the string size including the NULL, so
372  // compute len to include the terminating NULL.
373  //
374  status = RtlUShortAdd(imageName.Length, sizeof(UNICODE_NULL), &size);
375  if (!NT_SUCCESS(status)) {
377  "ERROR: size computation failed, %!status!\n", status);
378  goto cleanUp;
379  }
380 
381  //
382  // allocate a buffer to hold Unicode string + null char.
383  //
384  ImageName->Buffer = (PWCH) FxPoolAllocate(FxDriverGlobals, PagedPool, size);
385 
386  if (ImageName->Buffer == NULL) {
389  "ERROR: ExAllocatePoolWithTag failed, %!status!\n", status);
390  goto cleanUp;
391  }
392 
393  RtlZeroMemory(ImageName->Buffer, size);
394  ImageName->Length = 0x0;
395  ImageName->MaximumLength = size;
396 
397  HRESULT hr = StringCbCopy(ImageName->Buffer, size, imageName.Buffer);
398  if (FAILED(hr)) {
401  "ERROR: failed to copy string buffer, HRESULT 0x%x, %!status!\n",
402  hr, status);
403  goto cleanUp;
404  }
405 
406  //
407  // The copy cannot fail since we setup the buffer to hold enough space for
408  // the contents of the ImagePath value.
409  //
411 
412 cleanUp:
413 
414  if (!NT_SUCCESS(status)) {
415  if (ImageName->Buffer != NULL) {
416  FxPoolFree(ImageName->Buffer);
418  }
419  }
420 
421  if (dataBuffer != NULL) {
423  }
424 
425  return status;
426 }
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define USHORT_MAX
Definition: intsafe.h:147
Definition: pdh_main.c:93
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define _In_opt_
Definition: ms_sal.h:309
#define ERROR_SUCCESS
Definition: deptool.c:10
#define UMDF_CENSUS_EVT_WRITE_DEVICE_START(TraceHandle, Globals, DriverConfig, SetupClass, BusEnum, HwID, Manafacturer)
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
GLint x0
Definition: linetemp.h:95
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define _Out_
Definition: ms_sal.h:345
Definition: http.c:7251
BOOLEAN IsS0IdleSystemManaged(VOID)
Definition: fxpkgpnp.hpp:3645
#define KEY_READ
Definition: nt_native.h:1023
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
enum _WDF_DEVICE_IO_TYPE WDF_DEVICE_IO_TYPE
#define UMDF_FX_TRACE_LOGGING_PROVIDER_NAME
TRACELOGGING_DEFINE_PROVIDER(g_TelemetryProvider, UMDF_FX_TRACE_LOGGING_PROVIDER_NAME,(0x8ad60765, 0xa021, 0x4494, 0x85, 0x94, 0x93, 0x46, 0x97, 0x0c, 0xf5, 0x0f), TraceLoggingOptionMicrosoftTelemetry())
#define TRACINGDRIVER
Definition: dbgtrace.h:68
VOID LogDeviceStartTelemetryEvent(_In_ PFX_DRIVER_GLOBALS Globals, _In_opt_ FxDevice *Fdo)
VOID LogDriverInfoStream(_In_ PFX_DRIVER_GLOBALS DriverGlobals, _In_ FxDevice *Fdo)
DriverGlobals
uint16_t * PWCHAR
Definition: typedefs.h:56
struct _FX_TELEMETRY_CONTEXT * PFX_TELEMETRY_CONTEXT
PVOID dataBuffer
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_Must_inspect_result_ NTSTATUS GetImageName(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals, _Out_ PUNICODE_STRING ImageName)
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
CLIPBOARD_GLOBALS Globals
Definition: clipbrd.c:13
long RPC_STATUS
Definition: rpc.h:52
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
static __inline PVOID MxAllocatePoolWithTag(__in POOL_TYPE PoolType, __in SIZE_T NumberOfBytes, __in ULONG Tag)
Definition: mxmemorykm.h:30
long LONG
Definition: pedump.c:60
VOID RegisterTelemetryProvider(VOID)
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
const WCHAR * str
#define FX_TAG
Definition: fxmacros.hpp:155
#define FX_TELEMETRY_ENABLED(TraceHandle, Globals)
Definition: fxtelemetry.hpp:45
#define _In_
Definition: ms_sal.h:308
#define InterlockedBitTestAndSet
Definition: interlocked.h:30
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
GLsizeiptr size
Definition: glext.h:5919
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID AllocAndInitializeTelemetryContext(_In_ PFX_TELEMETRY_CONTEXT *TelemetryContext)
LONG HRESULT
Definition: typedefs.h:79
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
_In_opt_ PVOID _In_ ULONG _In_ PVOID context
Definition: wdfdriver.h:113
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
WCHAR * PWCH
Definition: ntbasedef.h:410
BOOLEAN IsPowerPolicyOwner(VOID)
Definition: fxpkgpnp.hpp:3612
VOID GetDriverInfo(_In_ FxDevice *Fdo, _In_ PUMDF_DRIVER_REGSITRY_INFO RegInfo, _Out_ UFxTelemetryDriverInfo *DriverInfo)
static const char * ImageName
Definition: image.c:34
#define StringCbCopy
Definition: strsafe.h:155
static const WCHAR L[]
Definition: oid.c:1250
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
BOOLEAN HasMultipleInterrupts(VOID)
Definition: fxpkgpnp.hpp:4066
DRIVER_INFORMATION DriverInfo
Definition: main.c:59
RPC_STATUS WINAPI UuidCreate(UUID *Uuid)
Definition: rpcrt4_main.c:303
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
FxAutoRegKey hKey
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
BOOLEAN __inline IsDeviceInfoFlagSet(_In_ USHORT DeviceInfo, _In_ FxDeviceInfoFlags Flag)
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
void exit(int exitcode)
Definition: _exit.c:33
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
void cleanUp()
Definition: main.cpp:472
BOOLEAN IsS0IdleWakeFromS0Enabled(VOID)
Definition: fxpkgpnp.hpp:3632
static SERVICE_STATUS status
Definition: service.c:31
VOID UnregisterTelemetryProvider(VOID)
#define RPC_S_UUID_LOCAL_ONLY
Definition: winerror.h:1131
VOID GetNameFromPath(_In_ PCUNICODE_STRING Path, _Out_ PUNICODE_STRING Name)
Definition: fxtelemetry.cpp:54
#define RPC_S_OK
Definition: rpcnterr.h:22
BOOLEAN IsS0IdleUsbSSEnabled(VOID)
Definition: fxpkgpnp.hpp:3658
BOOLEAN IsSxWakeEnabled(VOID)
Definition: fxpkgpnp.hpp:3672
#define REG_SZ
Definition: layer.c:22
Definition: ps.c:97