ReactOS  0.4.15-dev-3442-gc05a45e
tracingum.cpp File Reference
#include "FxSupportPch.hpp"
#include "fxldrum.h"
#include <strsafe.h>
#include <initguid.h>
#include "fxIFR.h"
#include "fxIFRKm.h"
Include dependency graph for tracingum.cpp:

Go to the source code of this file.

Functions

_Must_inspect_result_ NTSTATUS FxTraceInitialize (VOID)
 
VOID TraceUninitialize (VOID)
 
_Must_inspect_result_ NTSTATUS FxWmiQueryTraceInformation (__in TRACE_INFORMATION_CLASS, __out_bcount(TraceInformationLength) PVOID, __in ULONG, __out_opt PULONG, __in_opt PVOID)
 
_Must_inspect_result_ NTSTATUS FxWmiTraceMessage (__in TRACEHANDLE LoggerHandle, __in ULONG MessageFlags, __in LPGUID MessageGuid, __in USHORT MessageNumber,...)
 
ULONG FxIFRGetSize (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PCUNICODE_STRING RegistryPath)
 
VOID FxIFRStart (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PCUNICODE_STRING RegistryPath, __in MdDriverObject DriverObject)
 
VOID FxIFRStop (__in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
_Must_inspect_result_ NTSTATUS FxIFR (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in UCHAR MessageLevel, __in ULONG MessageFlags, __in LPGUID MessageGuid, __in USHORT MessageNumber,...)
 

Function Documentation

◆ FxIFR()

_Must_inspect_result_ NTSTATUS FxIFR ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in UCHAR  MessageLevel,
__in ULONG  MessageFlags,
__in LPGUID  MessageGuid,
__in USHORT  MessageNumber,
  ... 
)

Definition at line 613 of file tracingum.cpp.

645 {
646  size_t size;
648 
649  UNREFERENCED_PARAMETER( MessageLevel );
650 
651  //
652  // Return early if IFR is disabled.
653  //
655  ASSERT(FxDriverGlobals->WdfLogHeader == NULL);
656  return STATUS_SUCCESS;
657  }
658 
659  if ( FxDriverGlobals->WdfLogHeader == NULL) {
660  return STATUS_UNSUCCESSFUL;
661  }
662 
663 
664 
665 
666 
667 
668 
669 
670 
671 
672 
673 
674 
675 
676 
677 
678 
679 
680 
681 
682 
683 
684 
685 
686 
687  UNREFERENCED_PARAMETER( MessageFlags );
688 
689 
690  //
691  // Determine the number bytes to follow header
692  //
693  size = 0; // For Count of Bytes
694 
695  //
696  // Determine how much log space is needed for this
697  // trace record's data.
698  //
699  {
700  va_list ap;
701  size_t argLen;
702 
704 #pragma prefast(suppress: __WARNING_BUFFER_OVERFLOW, "Recommneded by EndClean");
705  while ((va_arg(ap, PVOID)) != NULL) {
706 
707  argLen = va_arg(ap, size_t);
708 
709  if (argLen > 0) {
710 
711  if (argLen > FxIFRMaxMessageSize) {
712  goto drop_message;
713  }
714  size += (USHORT) argLen;
715  }
716  }
717 
718  va_end(ap);
719 
720  //
721  // NOTE: The final size must be 32-bit (ULONG) aligned.
722  // This is necessary for IA64 to prevent Alignment Faults.
723  //
724  size += (size % sizeof(ULONG)) ? sizeof(ULONG) - (size % sizeof(ULONG)) : 0;
725 
726  if (size > FxIFRMaxMessageSize) {
727  goto drop_message;
728  }
729  }
730 
731  size += sizeof(WDF_IFR_RECORD);
732 
733  //
734  // Allocate log space of the calculated size
735  //
736  {
738  WDF_IFR_OFFSET offsetRet;
739  WDF_IFR_OFFSET offsetCur;
740  WDF_IFR_OFFSET offsetNew;
741  USHORT usSize = (USHORT) size; // for a prefast artifact.
742 
743  header = (PWDF_IFR_HEADER) FxDriverGlobals->WdfLogHeader;
744  ASSERT(header->Size < FxIFRMaxLogSize); // size doesn't include header.
745  ASSERT(header->Size >= header->Offset.u.s.Current);
746  ASSERT(header->Size >= header->Offset.u.s.Previous);
747 
748  offsetRet.u.AsLONG = header->Offset.u.AsLONG;
749  offsetNew.u.AsLONG = offsetRet.u.s.Current;
750 
751  do {
752  offsetCur.u.AsLONG = offsetRet.u.AsLONG;
753 
754  if (&header->Base[header->Size] < &header->Base[offsetCur.u.s.Current+size]) {
755 
756  offsetNew.u.s.Current = 0;
757  offsetNew.u.s.Previous = offsetRet.u.s.Previous;
758 
759  offsetRet.u.AsLONG =
760  InterlockedCompareExchange( &header->Offset.u.AsLONG,
761  offsetNew.u.AsLONG,
762  offsetCur.u.AsLONG );
763 
764  if (offsetCur.u.AsLONG != offsetRet.u.AsLONG) {
765  continue;
766  } else {
767  offsetNew.u.s.Current = offsetCur.u.s.Current + usSize;
768  offsetNew.u.s.Previous = offsetRet.u.s.Current;
769  }
770  } else {
771 
772  offsetNew.u.s.Current = offsetCur.u.s.Current + usSize;
773  offsetNew.u.s.Previous = offsetCur.u.s.Current;
774  }
775 
776  offsetRet.u.AsLONG =
777  InterlockedCompareExchange( &header->Offset.u.AsLONG,
778  offsetNew.u.AsLONG,
779  offsetCur.u.AsLONG );
780 
781  } while (offsetCur.u.AsLONG != offsetRet.u.AsLONG);
782 
783  record = (PWDF_IFR_RECORD) &header->Base[offsetRet.u.s.Current];
784 
785  // RtlZeroMemory( record, sizeof(WDF_IFR_RECORD) );
786 
787  //
788  // Build record (fill all fields!)
789  //
790  record->Signature = FxIFRRecordSignature;
791  record->Length = (USHORT) size;
792  record->PrevOffset = (USHORT) offsetRet.u.s.Previous;
793  record->MessageNumber = MessageNumber;
794  record->Sequence = InterlockedIncrement(header->SequenceNumberPointer);
795  record->MessageGuid = *MessageGuid;
796  }
797 
798  //
799  // Move variable part of data into log.
800  //
801  {
802  va_list ap;
803  size_t argLen;
804  PVOID source;
805  PUCHAR argsData;
806 
807  argsData = (UCHAR*) &record[1];
808 
810 #pragma prefast(suppress: __WARNING_BUFFER_OVERFLOW, "Recommneded by EndClean");
811  while ((source = va_arg(ap, PVOID)) != NULL) {
812 
813  argLen = va_arg(ap, size_t);
814 
815  if (argLen > 0) {
816 
817  RtlCopyMemory( argsData, source, argLen );
818  argsData += argLen;
819  }
820  }
821 
822  va_end(ap);
823  }
824 
825  return STATUS_SUCCESS;
826 
827  {
828  //
829  // Increment sequence number to indicate dropped message
830  //
831 drop_message:
833  header = (PWDF_IFR_HEADER) FxDriverGlobals->WdfLogHeader;
834  InterlockedIncrement(header->SequenceNumberPointer);
835  return STATUS_UNSUCCESSFUL;
836  }
837 }
LONG AsLONG
Definition: fxifr.h:83
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
unsigned char * PUCHAR
Definition: retypes.h:3
#define InterlockedCompareExchange
Definition: interlocked.h:104
struct _WDF_IFR_OFFSET::@4520::@4521 s
union _WDF_IFR_OFFSET::@4520 u
#define va_end(ap)
Definition: acmsvcex.h:90
char * va_list
Definition: acmsvcex.h:78
struct _WDF_IFR_HEADER * PWDF_IFR_HEADER
GLsizeiptr size
Definition: glext.h:5919
#define ASSERT(a)
Definition: mode.c:44
va_start(ap, x)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
struct _WDF_IFR_RECORD * PWDF_IFR_RECORD
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
struct _WDF_IFR_RECORD WDF_IFR_RECORD
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define InterlockedIncrement
Definition: armddk.h:53
unsigned short USHORT
Definition: pedump.c:61
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
_Must_inspect_result_ typedef _In_ ULONG _In_ ULONG MessageNumber
Definition: iotypes.h:4303
#define NULL
Definition: types.h:112
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
struct CFHEADER header
Definition: fdi.c:101

◆ FxIFRGetSize()

ULONG FxIFRGetSize ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PCUNICODE_STRING  RegistryPath 
)

Definition at line 357 of file tracingum.cpp.

374 {
375  FxAutoRegKey service, parameters;
377  ULONG numPages;
378 
379  //
380  // This is the value used in case of any error while retrieving 'LogPages'
381  // from the registry.
382  //
383  numPages = FxIFRMinLogPages;
384 
385  //
386  // External representation of the IFR is the "log", so use tha term when
387  // overriding the size via the registry.
388  //
389  DECLARE_CONST_UNICODE_STRING(parametersPath, L"Parameters\\Wdf");
390  DECLARE_CONST_UNICODE_STRING(valueName, L"LogPages");
391 
392  //
393  // UMDF may not provide this registry path
394  //
395  if (NULL == RegistryPath) {
396  goto defaultValues;
397  }
398 
399  status = FxRegKey::_OpenKey(NULL,
401  &service.m_Key,
402  KEY_READ);
403  if (!NT_SUCCESS(status)) {
404  goto defaultValues;
405  }
406 
407  status = FxRegKey::_OpenKey(service.m_Key,
408  (PCUNICODE_STRING)&parametersPath,
409  &parameters.m_Key,
410  KEY_READ);
411  if (!NT_SUCCESS(status)) {
412  goto defaultValues;
413  }
414 
415  status = FxRegKey::_QueryULong(parameters.m_Key, &valueName, &numPages);
416  if (!NT_SUCCESS(status)) {
417  goto defaultValues;
418  }
419 
420  if (numPages == 0) {
421  numPages = FxIFRMinLogPages;
422  }
423 
424 defaultValues:
425  //
426  // This behavior is different from KMDF. KMDF would allocate Average page count (5)
427  // if Verifier is on otherwise 1 page if the request is large.
428  // Since for UMDF the memory is coming from WudfRd, which does not know about verifier
429  // we will give it max pages here.
430  //
431  if (numPages > FxIFRMaxLogPages) {
432  numPages = FxIFRMaxLogPages;
433  }
434 
435  return numPages * PAGE_SIZE;
436 }
#define KEY_READ
Definition: nt_native.h:1023
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
#define L(x)
Definition: ntvdm.h:50
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by FxIFRStart().

◆ FxIFRStart()

VOID FxIFRStart ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PCUNICODE_STRING  RegistryPath,
__in MdDriverObject  DriverObject 
)

Definition at line 439 of file tracingum.cpp.

460 {
462  ULONG pageCount;
463  ULONG sizeCb;
464  HRESULT hr;
465  IWudfDeviceStack2 *pDeviceStack2;
466  PDRIVER_OBJECT_UM umDriverObject;
468  size_t bufferLengthCch;
469  ULONG allocatedBufferLengthCb;
470  LONG i;
471 
472  //
473  // Return early if IFR is disabled.
474  //
476  ASSERT(FxDriverGlobals->WdfLogHeader == NULL);
477  return;
478  }
479 
481 
482  if (FxDriverGlobals == NULL || FxDriverGlobals->WdfLogHeader != NULL) {
483  return;
484  }
485 
486  //
487  // It is safe to use StringCchLength here as WudfHost makes sure that this
488  // RegistryPath is null terminated
489  //
490  hr = StringCchLength(RegistryPath->Buffer,
491  RegistryPath->MaximumLength/sizeof(WCHAR),
492  &bufferLengthCch);
493 
494  if (FAILED(hr)) {
495  return;
496  }
497 
498  //
499  // Lets find the last '\' that will mark the begining of the service name
500  //
501  for (i = (ULONG)bufferLengthCch - 1;
502  i >= 0 && RegistryPath->Buffer[i] != '\\';
503  i--);
504 
505  //
506  // We did not find the service name
507  //
508  if (i < 0) {
509  return;
510  }
511 
512  serviceName = &RegistryPath->Buffer[i+1];
513 
514  sizeCb = FxIFRGetSize(FxDriverGlobals, RegistryPath);
515  pageCount = sizeCb / PAGE_SIZE;
516 
517  //
518  // Get the IWudfDeviceStack interface
519  //
520  umDriverObject = (PDRIVER_OBJECT_UM)DriverObject;
521 
522  pDeviceStack2 = (IWudfDeviceStack2 *)umDriverObject->WudfDevStack;
523 
524  if(pDeviceStack2 == NULL) {
525  return;
526  }
527 
528  allocatedBufferLengthCb = 0;
529  hr = pDeviceStack2->AllocateIfrMemory(serviceName,
530  pageCount,
531  FALSE,
532  TRUE,
533  (PVOID *)&pHeader,
534  &allocatedBufferLengthCb);
535 
536  if (pHeader == NULL || allocatedBufferLengthCb <= sizeof(WDF_IFR_HEADER)) {
537  return;
538  }
539 
540  //
541  // Initialize the header.
542  // Base will be where the IFR records are placed.
543  // WPP_ThisDir_CTLGUID_FrameworksTraceGuid
544  //
545  RtlCopyMemory(&pHeader->Guid, (PVOID) &WdfTraceGuid, sizeof(GUID));
546 
547  pHeader->Base = (PUCHAR) &pHeader[1];
548  pHeader->Size = allocatedBufferLengthCb - sizeof(WDF_IFR_HEADER);
549 
550  pHeader->Offset.u.s.Current = 0;
551  pHeader->Offset.u.s.Previous = 0;
552  pHeader->SequenceNumberPointer = &(DriverObject->IfrSequenceNumber);
553 
554  StringCchCopyA(pHeader->DriverName, WDF_IFR_HEADER_NAME_LEN, FxDriverGlobals->Public.DriverName);
555 
556  FxDriverGlobals->WdfLogHeader = pHeader;
557 
559  "FxIFR logging started" );
560 
561  if (sizeCb > FxIFRMinLogSize) {
563  FxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGDRIVER,
564  "FxIFR has been started with a size override: size 0x%x bytes, "
565  "# Pages %d. An extended IFR size may not be written to a minidump!",
566  sizeCb, sizeCb/PAGE_SIZE);
567  }
568 
569  if (sizeCb != allocatedBufferLengthCb) {
570  ASSERTMSG("FxIFR requested buffer size could not be allocated",FALSE);
572  FxDriverGlobals, TRACE_LEVEL_WARNING, TRACINGDRIVER,
573  "FxIFR requested an allocation of size 0x%x bytes, "
574  "Allocated memory was of size 0x%x bytes",
575  sizeCb, allocatedBufferLengthCb);
576  }
577 }
#define StringCchLength
Definition: strsafe.h:829
HRESULT hr
Definition: shlfolder.c:183
#define TRUE
Definition: types.h:120
WDFCASSERT(sizeof(WDF_DRIVER_CONFIG_V1_0)==sizeof(WDF_DRIVER_CONFIG_V1_1))
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
#define TRACINGDRIVER
Definition: dbgtrace.h:68
uint16_t * PWCHAR
Definition: typedefs.h:56
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
struct _WDF_IFR_HEADER WDF_IFR_HEADER
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
long LONG
Definition: pedump.c:60
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
FxContextHeader * pHeader
Definition: handleapi.cpp:604
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
char serviceName[]
Definition: tftpd.cpp:34
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
ULONG FxIFRGetSize(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PCUNICODE_STRING RegistryPath)
Definition: tracingum.cpp:357
LONG HRESULT
Definition: typedefs.h:79
struct _DRIVER_OBJECT_UM * PDRIVER_OBJECT_UM
Definition: mxum.h:165
#define PAGE_SIZE
Definition: env_spec_w32.h:49
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
#define WDF_IFR_HEADER_NAME_LEN
Definition: fxifr.h:42
#define WDF_IFR_RECORD_SIGNATURE
Definition: fxifr.h:109
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
IWudfDeviceStack2 * WudfDevStack
Definition: fxldrum.h:190

◆ FxIFRStop()

VOID FxIFRStop ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals)

Definition at line 580 of file tracingum.cpp.

598 {
599  UNREFERENCED_PARAMETER(FxDriverGlobals);
600 
601  //
602  // Uncomment the code below if you add any logic to this function.
603  //
604  // if (FxLibraryGlobals.IfrDisabled) {
605  // ASSERT(FxDriverGlobals->WdfLogHeader == NULL);
606  // return;
607  // }
608  //
609 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317

◆ FxTraceInitialize()

_Must_inspect_result_ NTSTATUS FxTraceInitialize ( VOID  )

Definition at line 256 of file tracingum.cpp.

278 {
279  //
280  // Initialize the tracing package.
281  //
283 
284  return STATUS_SUCCESS;
285 }
#define WPP_INIT_TRACING(a, b)
Definition: kdebugprint.h:56
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65

◆ FxWmiQueryTraceInformation()

Definition at line 310 of file tracingum.cpp.

317 {
318  return STATUS_UNSUCCESSFUL;
319 }
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

◆ FxWmiTraceMessage()

_Must_inspect_result_ NTSTATUS FxWmiTraceMessage ( __in TRACEHANDLE  LoggerHandle,
__in ULONG  MessageFlags,
__in LPGUID  MessageGuid,
__in USHORT  MessageNumber,
  ... 
)

Definition at line 323 of file tracingum.cpp.

330 {
332 
333  va_list va;
334  va_start(va, MessageNumber);
335  //
336  // UMDF is supported only on XP and newer OS so no need to support w2k
337  // tracing (which requires using a different tracing api, see kmdf impl)
338  //
339 #pragma prefast(suppress:__WARNING_BUFFER_OVERFLOW, "Recommneded by EndClean");
340  status = TraceMessageVa(LoggerHandle,
341  MessageFlags,
342  MessageGuid,
344  va);
345 
346  va_end(va);
347 
348  return status;
349 }
LONG NTSTATUS
Definition: precomp.h:26
#define va_end(ap)
Definition: acmsvcex.h:90
char * va_list
Definition: acmsvcex.h:78
EXTERN_C ULONG WMIAPI TraceMessageVa(IN TRACEHANDLE LoggerHandle, IN ULONG MessageFlags, IN LPCGUID MessageGuid, IN USHORT MessageNumber, IN va_list MessageArgList)
va_start(ap, x)
_Must_inspect_result_ typedef _In_ ULONG _In_ ULONG MessageNumber
Definition: iotypes.h:4303
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ TraceUninitialize()

VOID TraceUninitialize ( VOID  )

Definition at line 288 of file tracingum.cpp.

304 {
305  WPP_CLEANUP(NULL);
306 }
#define WPP_CLEANUP(a)
Definition: kdebugprint.h:57
#define NULL
Definition: types.h:112