Condividi tramite


Funzione EnableTraceEx2 (evntrace.h)

Un controller di sessione di traccia chiama EnableTraceEx2 per configurare il modo in cui un provider di eventi ETW registra gli eventi in una sessione di traccia.

Questa funzione sostituisce le funzioni di EnableTrace e EnableTraceEx.

Sintassi

ULONG WMIAPI EnableTraceEx2(
                 CONTROLTRACE_ID          TraceId,
  [in]           LPCGUID                  ProviderId,
  [in]           ULONG                    ControlCode,
  [in]           UCHAR                    Level,
  [in]           ULONGLONG                MatchAnyKeyword,
  [in]           ULONGLONG                MatchAllKeyword,
  [in]           ULONG                    Timeout,
  [in, optional] PENABLE_TRACE_PARAMETERS EnableParameters
);

Parametri

TraceId

[in] ProviderId

ID provider (GUID di controllo) del provider di eventi da configurare.

[in] ControlCode

È possibile specificare uno dei codici di controllo seguenti:

Valore Significato
EVENT_CONTROL_CODE_DISABLE_PROVIDER Aggiornare la configurazione della sessione in modo che la sessione non riceva eventi dal provider.
EVENT_CONTROL_CODE_ENABLE_PROVIDER Aggiornare la configurazione della sessione in modo che la sessione riceva gli eventi richiesti dal provider.
EVENT_CONTROL_CODE_CAPTURE_STATE Richiede che il provider registri le informazioni sullo stato.

[in] Level

Valore che indica il livello massimo di eventi che si desidera scrivere dal provider. Il provider scrive in genere un evento se il livello dell'evento è minore o uguale a questo valore, oltre a soddisfare i criteri MatchAnyKeyword e MatchAllKeyword.

Microsoft definisce la semantica dei livelli 1-5, come illustrato di seguito. I valori inferiori indicano eventi più gravi. Ogni valore di Livello abilita il livello specificato e tutti i livelli più gravi. Ad esempio, se si specifica TRACE_LEVEL_WARNING, il consumer riceverà avvisi, errori ed eventi critici.

Valore Significato
TRACE_LEVEL_CRITICAL (1) Eventi di uscita o terminazione anomali
TRACE_LEVEL_ERROR (2) Eventi di errore gravi
TRACE_LEVEL_WARNING (3) Eventi di avviso, ad esempio errori di allocazione
TRACE_LEVEL_INFORMATION (4) Eventi informativi non di errore
TRACE_LEVEL_VERBOSE (5) Eventi di diagnostica dettagliati

Le costanti TRACE_LEVEL sono definite in evntrace.h. Le costanti WINMETA_LEVEL equivalenti vengono definite in winmeta.h.

[in] MatchAnyKeyword

Maschera a 64 bit di parole chiave che determinano le categorie di eventi che si desidera che il provider scriva. Il provider scrive in genere un evento se i bit della parola chiave dell'evento corrispondono qualsiasi dei bit impostati in questo valore o se l'evento non ha bit di parola chiave impostati, oltre a soddisfare i criteri di Level e MatchAllKeyword.

[in] MatchAllKeyword

Maschera di parole chiave a 64 bit che limita gli eventi che si desidera che il provider scriva. Il provider scrive in genere un evento se i bit della parola chiave dell'evento corrispondono tutti i dei bit impostati in questo valore o se l'evento non ha bit di parola chiave impostati, oltre a soddisfare i criteri di Level e MatchAnyKeyword.

Questo valore viene spesso impostato su 0.

[in] Timeout

Se timeout è 0, questa funzione inizierà a configurare il provider in modo asincrono e restituirà immediatamente (ad esempio, restituirà senza attendere il completamento dei callback del provider).

In caso contrario, questa funzione inizierà a configurare il provider e inizierà ad attendere il completamento della configurazione, incluso l'attesa del completamento di tutti i callback del provider. Se la configurazione viene completata prima del timeout specificato, questa funzione restituirà ERROR_SUCCESS. In caso contrario, questa funzione restituirà ERROR_TIMEOUT.

Per attendere per sempre, impostare su INFINITE.

[in, optional] EnableParameters

Parametri di traccia usati per abilitare il provider. Per informazioni dettagliate, vedere ENABLE_TRACE_PARAMETERS.

Valore restituito

Se la funzione ha esito positivo, il valore restituito viene ERROR_SUCCESS.

Se la funzione ha esito negativo, il valore restituito è uno dei codici di errore di sistema . Di seguito sono riportati alcuni errori comuni e le relative cause.

  • ERROR_INVALID_PARAMETER

    Un parametro non è corretto.

    Questo problema può verificarsi se uno dei seguenti è true:

    • Il ProviderId NULL.
    • Il TraceHandle è 0.
  • ERROR_TIMEOUT

    Valore di timeout scaduto prima del completamento del callback di abilitazione. Per informazioni dettagliate, vedere il parametro timeout.

  • ERROR_INVALID_FUNCTION

    Non è possibile aggiornare il livello quando il provider non è registrato.

  • ERROR_NO_SYSTEM_RESOURCES

    È stato superato il numero di sessioni di traccia che possono abilitare il provider.

  • ERROR_ACCESS_DENIED

    Solo gli utenti con privilegi amministrativi, gli utenti nel gruppo di Performance Log Users e i servizi in esecuzione come LocalSystem, LocalServiceo NetworkService possono abilitare i provider di eventi a una sessione tra processi. Per concedere a un utente limitato la possibilità di abilitare un provider di eventi, aggiungerli al gruppo di Performance Log Users o vedere EventAccessControl.

    Windows XP e Windows 2000: Chiunque può abilitare un provider di eventi.

Osservazioni

I controller di traccia eventi chiamano questa funzione per configurare i provider di eventi che scrivono eventi nella sessione. Ad esempio, un controller potrebbe chiamare questa funzione per iniziare a raccogliere eventi da un provider, per regolare il livello o le parole chiave degli eventi raccolti da un provider o per interrompere la raccolta di eventi da un provider.

Il comportamento di abilitazione per un provider dipende dalle API usate dal provider.

  • Un provider che usa RegisterTraceGuids (ad esempio, un provider che usa WPP o MOF basato su TMF) usa il sistema di abilitazione legacy (talvolta denominato "ETW classico"). Quando un provider legacy è abilitato o riconfigurato per una sessione, il runtime ETW invia una notifica al provider e fornisce l'accesso al livello, i 32 bit bassi della maschera MatchAnyKeyword e l'ID sessione. Il provider usa quindi la propria logica per decidere quali eventi devono essere abilitati e inviati direttamente alla sessione specificata. I dati dell'evento inviati a ETW in fase di esecuzione includono il GUID decodifica dell'evento e l'ID del messaggio, ma non include il GUID del controllo dell'evento, il livello o le parole chiave. ETW verifica che il provider disponga delle autorizzazioni necessarie e quindi aggiunge i dati dell'evento alla sessione specificata.
    • Poiché gli eventi vengono inviati direttamente a una sessione specifica senza GUID di controllo, informazioni sul livello o sulle parole chiave, ETW non può eseguire alcun filtro o routing aggiuntivo per i provider che usano il sistema di abilitazione legacy. Ogni evento può essere indirizzato a non più di una sessione.
  • Un provider che usa EventRegister (ad esempio, un provider basato su manifesto o un provider TraceLogging) usa il sistema di abilitazione moderno (talvolta denominato "crimson ETW"). Quando un provider moderno è abilitato o riconfigurato per una sessione, il runtime ETW invia una notifica al provider con il livello, la maschera MatchAnyKeyword a 64 bit, la maschera MatchAllKeyword a 64 bit e tutti i dati di filtro lato provider personalizzati specificati dal controller di traccia. Il provider usa quindi la propria logica per decidere quali eventi devono essere abilitati, anche se la maggior parte dei provider duplica solo la logica di EventProviderEnabled. Il provider invia gli eventi abilitati a ETW per il routing. I dati dell'evento inviati a ETW includono il GUID del controllo dell'evento, l'ID del messaggio, il livello e le parole chiave. ETW esegue quindi filtri aggiuntivi in base alle esigenze, instradando l'evento alle sessioni appropriate.
    • Poiché gli eventi vengono inviati a ETW con informazioni descrittive, ETW può eseguire ulteriori filtri e routing prima di aggiungere l'evento alla sessione. Gli eventi possono essere indirizzati a più sessioni, se appropriato.

Per i provider che usano il sistema di abilitazione moderno (ad esempio provider che usano EventRegister), ETW supporta diverse funzionalità che possono essere richieste dal controller di sessione di traccia tramite EnableTraceEx2EnableParameters. Per informazioni dettagliate, vedere EVENT_FILTER_DESCRIPTOR.

  • di filtro schematizzato: questa è la configurazione tradizionale del filtro, detta anche filtro lato provider. Il controller definisce un set personalizzato di filtri come oggetto binario passato al provider in EnableCallbackFilterData. È in carica nel controller e nel provider definire e interpretare questi filtri. Il provider può quindi utilizzare il parametroFilter EventWriteEx per indicare le sessioni a cui non deve essere inviato un evento a causa del filtro sul lato provider. Ciò richiede un accoppiamento stretto del controller e del provider perché il tipo e il formato dell'oggetto binario di ciò che è possibile filtrare non è definito. La funzione TdhEnumerateProviderFilters può essere usata per recuperare i filtri definiti in un manifesto.
  • filtro dell'ambito: alcuni provider sono abilitati o meno per una sessione in base al fatto che soddisfino o meno i criteri specificati dai filtri di ambito. Esistono diversi tipi di filtri di ambito che consentono di filtrare in base all'ID processo (PID), al nome file eseguibile, all'ID app e al nome del pacchetto dell'app. Questa funzionalità è supportata in Windows 8.1, Windows Server 2012 R2 e versioni successive.
  • filtro stackwalk: notifica a ETW di eseguire solo una procedura dettagliata dello stack per un determinato set di ID evento o (per gli eventi TraceLogging). Questa funzionalità è supportata in Windows 8.1, Windows Server 2012 R2 e versioni successive.
  • filtro attributi: per i provider di manifesto, gli eventi possono essere filtrati in base agli attributi dell'evento, ad esempio livello, parola chiave, ID evento o nome evento.
  • filtro del payload dell'evento: per i provider di manifesto, gli eventi possono essere filtrati in tempo reale in base al fatto che soddisfino o meno un'espressione logica in base a uno o più predicati.

Nota

Anche se ETW supporta potenti filtri di payload e attributi, gli eventi devono essere filtrati principalmente in base ai filtri di ambito o tramite GUID di controllo, livello e parola chiave. I provider in genere eseguono il filtro GUID, il livello e la parola chiave del controllo direttamente nel codice del provider prima che l'evento venga generato o inviato a ETW. Nella maggior parte dei provider, gli eventi disabilitati per livello o parola chiave non hanno quasi alcun impatto sulle prestazioni del sistema. Analogamente, i provider disabilitati dai filtri di ambito non hanno quasi alcun impatto sulle prestazioni del sistema. Altri tipi di filtro (basati su payload o attributi diversi da livello e parola chiave) vengono in genere eseguiti dopo che il provider ha generato l'evento e lo ha inviato al runtime ETW, ovvero l'evento ha un impatto sulle prestazioni del sistema (il tempo di CPU dedicato alla preparazione dell'evento e l'invio a ETW) anche se il filtro ETW determina che l'evento non deve essere registrato da alcuna sessione. Questo tipo di filtro è efficace solo per ridurre il volume di dati di traccia e non è altrettanto efficace per ridurre il sovraccarico della CPU di traccia.

Ogni volta che viene chiamato enableTraceEx2, i filtri per il provider in tale sessione vengono sostituiti dai nuovi parametri definiti dai parametri passati alla funzione EnableTraceEx2. È possibile combinare più filtri passati in una singola chiamata a EnableTraceEx2 con un effetto aggiuntivo, ma i filtri passati in una chiamata successiva sostituiranno il set di filtri precedente.

Per disabilitare il filtro e quindi abilitare tutti i provider/eventi nella sessione di registrazione, chiamare EnableTraceEx2 con il parametro EnableParameters che punta a una struttura ENABLE_TRACE_PARAMETERS con il membro FilterDescCount impostato su 0.

Ogni filtro passato alla funzione EnableTraceEx2 viene specificato da un membro Type nel EVENT_FILTER_DESCRIPTOR. Una matrice di strutture di EVENT_FILTER_DESCRIPTOR viene passata nella struttura ENABLE_TRACE_PARAMETERS passata al parametro EnableParameters alla funzione EnableTraceEx2 .

Ogni tipo di filtro (un tipo specifico membro) può essere visualizzato solo una volta in una chiamata alla funzione EnableTraceEx2. Alcuni tipi di filtro consentono l'inserimento di più condizioni in un singolo filtro. Il numero massimo di filtri che possono essere inclusi in una chiamata a EnableTraceEx2 viene impostato da MAX_EVENT_FILTERS_COUNT (definito nel file di intestazione Evntprov.h; il valore può cambiare nelle versioni future di Windows SDK).

Ogni tipo di filtro ha limiti di dimensioni o entità specifici in base al membro Type specifico nella struttura EVENT_FILTER_DESCRIPTOR. L'elenco seguente indica questi limiti.

  • EVENT_FILTER_TYPE_SCHEMATIZED

    • Limite di dimensioni filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: definito dal provider e dal controller
  • EVENT_FILTER_TYPE_PID

    • Limite di dimensioni filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: MAX_EVENT_FILTER_PID_COUNT (8)
  • EVENT_FILTER_TYPE_EXECUTABLE_NAME

    • Limite di dimensioni filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: una singola stringa che può contenere più nomi di file eseguibili separati da punti e virgola.
  • EVENT_FILTER_TYPE_PACKAGE_ID

    • Limite di dimensioni filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: una singola stringa che può contenere più ID pacchetto separati da punti e virgola.
  • EVENT_FILTER_TYPE_PACKAGE_APP_ID

    • Limite di dimensioni filtro: MAX_EVENT_FILTER_DATA_SIZE (1024)
    • Numero di elementi consentiti: una singola stringa che può contenere più ID app relativi al pacchetto (PRAID) separati da punti e virgola.
  • EVENT_FILTER_TYPE_PAYLOAD

    • Limite di dimensioni filtro: MAX_EVENT_FILTER_PAYLOAD_SIZE (4096)
    • Numero di elementi consentiti: 1
  • EVENT_FILTER_TYPE_EVENT_ID

    • Limite di dimensioni filtro: non definito
    • Numero di elementi consentiti: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)
  • EVENT_FILTER_TYPE_STACKWALK

    • Limite di dimensioni filtro: non definito
    • Numero di elementi consentiti: MAX_EVENT_FILTER_EVENT_ID_COUNT (64)

Le parole chiave definiscono le categorie di eventi. Ad esempio, se il provider definisce InitializationKeyword = 0x1 (bit parola chiave 0), FileOperationKeyword = 0x2 (bit parola chiave 1) e CalculationKeyword = 0x4 (parola chiave bit 2), è possibile impostare MatchAnyKeyword su (InitializationKeyword | CalculationKeyword) = 5 per ricevere eventi di inizializzazione e calcolo, ma non eventi di file.

Se usato con provider moderni ( basati su manifesto o TraceLogging), un valore MatchAnyKeyword di 0 viene considerato uguale a un valore MatchAnyKeyword di 0xFFFFFFFFFFFFFFFF, ovvero abilita tutte le parole chiave dell'evento. Tuttavia, questo comportamento non si applica ai provider WPPbasati su MOF o TMFlegacy. Per abilitare tutte le parole chiave evento da un provider legacy, impostare MatchAnyKeyword su 0xFFFFFFFF. Per abilitare tutte le parole chiave evento di provider legacy e moderni, impostare MatchAnyKeyword su 0xFFFFFFFFFFFFFFFF.

Se la parola chiave di un evento è zero, il provider scriverà l'evento nella sessione indipendentemente dalle maschere MatchAnyKeyword e MatchAllKeyword. Questo comportamento può essere disabilitato usando il flag EVENT_ENABLE_PROPERTY_IGNORE_KEYWORD_0.

Per indicare che si vuole abilitare un gruppo di provider, usare il flag di nel membro EnableProperty di EnableParameters.

Quando si chiama EnableTraceEx2, il provider potrebbe o non essere già registrato. Se il provider è già registrato, ETW chiama la funzione di callback del provider (se presente) e la sessione inizia a ricevere eventi. Se il provider non è già registrato, ETW chiamerà la funzione di callback del provider (se presente) immediatamente dopo la registrazione del provider e la sessione inizierà a ricevere eventi. Se il provider non è già registrato, la funzione di callback del provider non riceverà l'ID di origine.

Se il provider è registrato e già abilitato per la sessione, è possibile chiamare di nuovo EnableTraceEx2 per aggiornare i parametriLevel , MatchAnyKeyword, parametri MatchAllKeyword e EnableProperty e EnableFilterDesc membri di EnableParameters.

In Windows 8.1, Windows Server 2012 R2 e versioni successive, il payload degli eventi, l'ambito e i filtri di procedura dettagliata dello stack possono essere usati dalla funzione EnableTraceEx2 e dalle strutture ENABLE_TRACE_PARAMETERS e EVENT_FILTER_DESCRIPTOR per filtrare in base a condizioni specifiche in una sessione del logger. Per altre informazioni sui filtri del payload degli eventi, vedere le funzioni TdhCreatePayloadFiltere TdhAggregatePayloadFilters e le strutture ENABLE_TRACE_PARAMETERS, EVENT_FILTER_DESCRIPTORe PAYLOAD_FILTER_PREDICATE.

Non è possibile abilitare o disabilitare eventi speciali del provider di traccia di sistema EnableTraceEx2. Possono essere abilitati solo tramite il campo EnableFlags di EVENT_TRACE_PROPERTIES quando la traccia viene avviata per la prima volta da StartTrace.

A partire da Windows 11, gli eventi del provider di traccia di sistema possono essere abilitati tramite EnableTraceEx2.

Fino a otto sessioni di traccia possono abilitare e ricevere eventi dallo stesso provider moderno ( basato su manifesto o TraceLogging). Tuttavia, solo una sessione di traccia può abilitare un provider WPP (MOF, TMF) legacy. Se più sessioni tentano di abilitare un provider legacy, la prima sessione smette di ricevere eventi quando la seconda sessione abilita lo stesso provider. Ad esempio, se la sessione A ha abilitato un provider legacy e quindi la sessione B ha abilitato lo stesso provider, solo la sessione B riceverà eventi da tale provider.

Un provider rimane abilitato per la sessione fino a quando la sessione non disabilita il provider. Se l'applicazione che ha avviato la sessione termina senza disabilitare il provider, il provider rimane abilitato.

Per determinare il livello e le parole chiave usate per abilitare un provider basato su manifesto, usare uno dei comandi seguenti:

  • Provider di query logman provider-name
  • wevtutil gp provider-name

Per i provider classici, spetta al provider documentare e rendere disponibili ai potenziali controller i livelli di gravità o abilitare i flag supportati. Se il provider vuole essere abilitato da qualsiasi controller, il provider deve accettare 0 per il livello di gravità e abilitare i flag e interpretare 0 come richiesta di eseguire la registrazione predefinita (qualunque sia).

Se si usa EnableTraceEx2 per abilitare un provider classico, si verifica la conversione seguente:

  • Il parametro Level di equivale all'impostazione del parametro EnableLevel in EnableTrace.
  • Il MatchAnyKeyword equivale all'impostazione del parametro EnableFlag in EnableTrace ad eccezione del fatto che il valore della parola chiave viene troncato da un valore a 64 bit a un valore a 32 bit.
  • Nel callback ControlCallback, il provider può chiamare GetTraceEnableLevel per ottenere il livello e GetTraceEnableFlags per ottenere il flag di abilitazione.
  • L'altro parametro non viene utilizzato.

Esempi

L'esempio seguente illustra l'uso del EnableTraceEx2 con filtri di payload usando il TdhCreatePayloadFilter e TdhAggregatePayloadFilters funzioni per filtrare in base a condizioni specifiche in una sessione del logger.

#define INITGUID
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <strsafe.h>
#include <evntrace.h>
#include <tdh.h>

#define MAXIMUM_SESSION_NAME 1024

#define PATH_TO_MANIFEST_FILE L"c:\\ExampleManifest.man"

//
// The following definitions would be found in the include file generated by
// message compiler from the manifest file.
//

// Provider Example-Provider Event Count 2
EXTERN_C __declspec(selectany) const GUID EXAMPLE_PROVIDER = {0x37a59b93, 0xbb25, 0x4cee, {0x97, 0xaa, 0x8b, 0x6a, 0xcd, 0xc, 0x4d, 0xf8}};

//
// Event Descriptors
//
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_1 = { 0x1, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_1_value 0x1
EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Example_Event_2 = { 0x2, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0 };
#define Example_Event_2_value 0x2

//
// (End of snippet from include file)
//

// Allocate an EVENT_TRACE_PROPERTIES structure and set the needed logging session properties
PEVENT_TRACE_PROPERTIES AllocateTraceProperties(
    _In_opt_ PCWSTR LoggerName,
    _In_opt_ PCWSTR LogFileName
)
{
    PEVENT_TRACE_PROPERTIES TraceProperties = NULL;
    ULONG BufferSize;

    BufferSize = sizeof(EVENT_TRACE_PROPERTIES) +
        (MAXIMUM_SESSION_NAME + MAX_PATH) * sizeof(WCHAR);

    TraceProperties = (PEVENT_TRACE_PROPERTIES)malloc(BufferSize);
    if (TraceProperties == NULL) {
        printf("Unable to allocate %d bytes for properties structure.\n", BufferSize);
        goto Exit;
    }

    //
    // Set the session properties.
    //
    ZeroMemory(TraceProperties, BufferSize);
    TraceProperties->Wnode.BufferSize = BufferSize;
    TraceProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
    TraceProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
    TraceProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) +
        (MAXIMUM_SESSION_NAME * sizeof(WCHAR));

    if (LoggerName != NULL) {
        StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LoggerNameOffset),
            MAXIMUM_SESSION_NAME,
            LoggerName);
    }

    if (LogFileName != NULL) {
        StringCchCopyW((LPWSTR)((PCHAR)TraceProperties + TraceProperties->LogFileNameOffset),
            MAX_PATH,
            LogFileName);
    }

Exit:
    return TraceProperties;
}

// Free the EVENT_TRACE_PROPERTIES structure previously allocated
VOID FreeTraceProperties(
    _In_ PEVENT_TRACE_PROPERTIES TraceProperties
)
{
    free(TraceProperties);
    return;
}

// Set the values needed in a PAYLOAD_FILTER_PREDICATE for a single payload filter
FORCEINLINE VOID PayloadPredicateCreate(
    _Out_ PAYLOAD_FILTER_PREDICATE* Predicate,
    _In_ PCWSTR FieldName,
    USHORT CompareOp,
    PCWSTR Value
)
{
    Predicate->FieldName = (PWSTR)FieldName;
    Predicate->CompareOp = CompareOp;
    Predicate->Value = (PWSTR)Value;
    return;
}

int __cdecl wmain()
{
    UINT i;
    PVOID EventFilters[2];
    EVENT_FILTER_DESCRIPTOR FilterDescriptor;
    UINT PredicateCount;
    PAYLOAD_FILTER_PREDICATE Predicates[3];
    ULONG FilterCount;
    ULONG Status = ERROR_SUCCESS;
    TRACEHANDLE SessionHandle = 0;
    PEVENT_TRACE_PROPERTIES TraceProperties;
    BOOLEAN TraceStarted = FALSE;
    PCWSTR LoggerName = L"MyTrace";
    ENABLE_TRACE_PARAMETERS EnableParameters;

    ZeroMemory(EventFilters, sizeof(EventFilters));
    ZeroMemory(Predicates, sizeof(Predicates));
    TraceProperties = NULL;
    FilterCount = 0;

    //
    // Load the manifest for the provider
    //
    Status = TdhLoadManifest((PWSTR)PATH_TO_MANIFEST_FILE);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Create predicates that match the following high-level expression:
    //
    // INCLUDE Example_Event_1 IF
    //     Example_Event_1.Initiator == "User" AND
    //     7 <= Example_Event_1.Level <= 16
    //
    PredicateCount = 0;

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        (PWSTR)L"Initiator",
        PAYLOADFIELD_IS,
        (PWSTR)L"User");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"Level",
        PAYLOADFIELD_BETWEEN,
        L"7,16");

    Status = TdhCreatePayloadFilter(
        &EXAMPLE_PROVIDER,
        &Example_Event_1,
        FALSE,      // Match all predicates (AND)
        PredicateCount,
        Predicates,
        &EventFilters[FilterCount++]);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Create predicates that match the following high-level expression:
    // INCLUDE Example_Event_2 IF
    //      Example_Event_2.Title CONTAINS "UNI" OR
    //      Example_Event_2.InstanceId == {0E95CFBC-58D4-44BA-BE40-E63A853536DF} OR
    //      Example_Event_2.ErrorCode != 0      //
    PredicateCount = 0;

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"Title",
        PAYLOADFIELD_CONTAINS,
        L"UNI");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"InstanceId",
        PAYLOADFIELD_IS,
        L" {0E95CFBC-58D4-44BA-BE40-E63A853536DF}");

    PayloadPredicateCreate(
        &Predicates[PredicateCount++],
        L"ErrorCode",
        PAYLOADFIELD_NE,
        L"0");

    Status = TdhCreatePayloadFilter(
        &EXAMPLE_PROVIDER,
        &Example_Event_2,
        FALSE,      // Match any predicates (OR)
        PredicateCount,
        Predicates,
        &EventFilters[FilterCount++]);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCreatePayloadFilter() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Combine the interim filters into a final filter descriptor.
    //
    Status = TdhAggregatePayloadFilters(
        FilterCount,
        EventFilters,
        NULL,
        &FilterDescriptor);
    if (Status != ERROR_SUCCESS) {
        printf("TdhAggregatePayloadFilters() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Clean up the interim filters
    //
    for (i = 0; i < FilterCount; i++) {

        Status = TdhDeletePayloadFilter(&EventFilters[i]);
        if (Status != ERROR_SUCCESS) {
            printf("TdhDeletePayloadFilter() failed with %lu\n", Status);
            goto Exit;
        }
    }

    //
    // Create a new trace session
    //
    //
    // Allocate EVENT_TRACE_PROPERTIES structure and perform some
    // basic initialization.
    //
    // N.B. LoggerName will be populated during StartTrace call.
    //
    TraceProperties = AllocateTraceProperties(NULL, L"SystemTrace.etl");
    if (TraceProperties == NULL) {
        Status = ERROR_OUTOFMEMORY;
        goto Exit;
    }

    TraceProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL | EVENT_TRACE_SYSTEM_LOGGER_MODE;
    TraceProperties->MaximumFileSize = 100; // Limit file size to 100MB max
    TraceProperties->BufferSize = 512; // Use 512KB trace buffers
    TraceProperties->MinimumBuffers = 8;
    TraceProperties->MaximumBuffers = 64;

    Status = StartTraceW(&SessionHandle, LoggerName, TraceProperties);
    if (Status != ERROR_SUCCESS) {
        printf("StartTrace() failed with %lu\n", Status);
        goto Exit;
    }

    TraceStarted = TRUE;

    //
    // Enable the provider to a trace session with filtering enabled on the
    // provider
    //
    ZeroMemory(&EnableParameters, sizeof(EnableParameters));
    EnableParameters.Version = ENABLE_TRACE_PARAMETERS_VERSION_2;
    EnableParameters.EnableFilterDesc = &FilterDescriptor;
    EnableParameters.FilterDescCount = 1;

    Status = EnableTraceEx2(
        SessionHandle,
        &EXAMPLE_PROVIDER,
        EVENT_CONTROL_CODE_ENABLE_PROVIDER,
        TRACE_LEVEL_VERBOSE,
        0,
        0,
        0,
        &EnableParameters);
    if (Status != ERROR_SUCCESS) {
        printf("EnableTraceEx2() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Clean up the payload descriptor
    //
    Status = TdhCleanupPayloadEventFilterDescriptor(&FilterDescriptor);
    if (Status != ERROR_SUCCESS) {
        printf("TdhCleanupPayloadEventFilterDescriptor() failed with %lu\n", Status);
        goto Exit;
    }

    //
    // Collect trace for 30 seconds
    //
    Sleep(30 * 1000);

Exit:

    //
    // Stop tracing.
    //
    if (TraceStarted != FALSE) {
        Status = ControlTraceW(SessionHandle, NULL, TraceProperties, EVENT_TRACE_CONTROL_STOP);
        if (Status != ERROR_SUCCESS) {
            printf("StopTrace() failed with %lu\n", Status);
        }
    }

    if (TraceProperties != NULL) {
        FreeTraceProperties(TraceProperties);
    }

    TdhUnloadManifest((PWSTR)PATH_TO_MANIFEST_FILE);

    return Status;
}

Fabbisogno

Requisito Valore
client minimo supportato Windows 7 [app desktop | App UWP]
server minimo supportato Windows Server 2008 R2 [app desktop | App UWP]
piattaforma di destinazione Finestre
intestazione evntrace.h
libreria Sechost.lib in Windows 8.1 e Windows Server 2012 R2; Advapi32.lib in Windows 8, Windows Server 2012, Windows 7 e Windows Server 2008 R2
dll Sechost.dll in Windows 8.1 e Windows Server 2012 R2; Advapi32.dll in Windows 8, Windows Server 2012, Windows 7 e Windows Server 2008 R2

Vedere anche

StartTrace

ControlTrace

EnableCallback

ENABLE_TRACE_PARAMETERS

EVENT_FILTER_DESCRIPTOR