Funzione EtwWrite (wdm.h)
La funzione EtwWrite è una funzione di traccia per la pubblicazione di eventi nel codice driver in modalità kernel.
Sintassi
NTSTATUS EtwWrite(
[in] REGHANDLE RegHandle,
[in] PCEVENT_DESCRIPTOR EventDescriptor,
[in, optional] LPCGUID ActivityId,
[in] ULONG UserDataCount,
[in, optional] PEVENT_DATA_DESCRIPTOR UserData
);
Parametri
[in] RegHandle
Puntatore all'handle di registrazione del provider di eventi, che viene restituito dalla funzione EtwRegister se la registrazione del provider di eventi ha esito positivo.
[in] EventDescriptor
Puntatore alla struttura EVENT_DESCRIPTOR .
[in, optional] ActivityId
Identificatore che indica l'attività associata all'evento. ActivityID consente di raggruppare gli eventi correlati e viene usato nella traccia end-to-end.
[in] UserDataCount
Numero di strutture EVENT_DATA_DESCRIPTOR in UserData.
[in, optional] UserData
Puntatore alla matrice di strutture EVENT_DATA_DESCRIPTOR.
Valore restituito
Se l'evento è stato pubblicato correttamente, EtwWrite restituisce STATUS_SUCCESS.
Se il puntatore all'handle di registrazione del provider di eventi non è valido, EtwWrite restituisce STATUS_INVALID_HANDLE. Il provider di eventi deve essere registrato prima di chiamare EtwWrite . EtwWrite può anche restituire STATUS_INVALID_HANDLE se non è in grado di registrare l'evento.
Se il numero di strutture EVENT_DATA_DESCRIPTOR specificate in UserDataCount è maggiore del massimo consentito (128), EtwWrite restituisce STATUS_INVALID_PARAMETER.
Se è specificato ActivityID , ma non è disponibile memoria sufficiente per registrare i dati associati all'evento, EtwWrite restituisce STATUS_NO_MEMORY.
Se il provider non è abilitato per alcuna sessione, EtwWrite restituisce STATUS_SUCCESS e gli eventi non vengono registrati.
Gli eventi possono essere persi per diversi motivi; ad esempio, se la frequenza degli eventi è troppo elevata o se la dimensione dell'evento è maggiore della dimensione del buffer. In questi casi, il contatore EventsLost , un membro della struttura EVENT_TRACE_PROPERTIES per il logger corrispondente, viene aggiornato con il numero di eventi non registrati.
Commenti
La funzione EtwWrite è l'equivalente in modalità kernel della funzione EventWrite in modalità utente. Per assicurarsi che sia presente un consumer per l'evento che si sta pubblicando, è possibile precedere la chiamata a EtwWrite con una chiamata a EtwEventEnabled o EtwProviderEnabled.
Prima di poter chiamare la funzione EtwWrite per pubblicare un evento, è necessario registrare il provider con EtwRegister. Non è necessario effettuare chiamate di traccia che non rientrano nel codice delimitato dalle funzioni EtwRegister e EtwUnregister . Per ottenere prestazioni ottimali, è possibile chiamare la funzione EtwRegister nella routine DriverEntry e la funzione EtwUnregister nella routine DriverUnload .
Se si usa il parametro UserData facoltativo nella funzione EtwWrite per registrare dati di eventi aggiuntivi, è possibile utilizzare la macro EventDataDescCreate per semplificare la creazione delle strutture EVENT_DATA_DESCRIPTOR. Nell'esempio seguente viene utilizzata la macro EventDataDescCreate per inizializzare EVENT_DATA_DESCRIPTOR strutture con il nome del dispositivo e il relativo stato. La macro EventDataDescCreate archivia i puntatori ai dati, ovvero non archivia copie dei dati. I puntatori devono rimanere validi fino a quando non viene restituita la chiamata a EtwWrite .
È possibile chiamare EtwWrite in qualsiasi IRQL. Tuttavia, quando IRQL è maggiore di APC_LEVEL, i dati passati alle funzioni EtwWrite, EtwWriteEx, EtwWriteString, EtwWriteTransfer non devono essere pageable. Ovvero, qualsiasi routine in modalità kernel in esecuzione in IRQL maggiore di APC_LEVEL non può accedere alla memoria di paging. I dati passati alle funzioni EtwWrite, EtwWriteEx, EtwWriteString e EtwWriteTransfer devono risiedere nella memoria dello spazio di sistema, indipendentemente dal valore di IRQL.
Esempio
//
// Register the provider with ETW in DriverEntry
// Unregister the provider in DriverUnload
//
// Build the EVENT_DATA_DESCRIPTOR structures using
// the EventDataDescCreate macros
if (RegHandle != (REGHANDLE)NULL) {
//
// Log an Event with : DeviceNameLength
// DeviceName
// Status
//
EventDataDescCreate(&EventDataDescriptor[0],
(PVOID)&DeviceName.Length,
sizeof(USHORT));
EventDataDescCreate(&EventDataDescriptor[1],
(PVOID)DeviceName.Buffer,
DeviceName.Length);
EventDataDescCreate(&EventDataDescriptor[2],
(PVOID)&Status,
sizeof(ULONG));
EtwWrite(RegHandle, // Handle from EtwRegister
&StartEvent, // EventDescriptor
NULL, // Activity ID
3, // Number of data items
EventDataDescriptor); // Array of data descriptors
}
//
Requisiti
Requisito | Valore |
---|---|
Piattaforma di destinazione | Universale |
Intestazione | wdm.h (include Wdm.h, Ntddk.h) |
Libreria | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | Qualsiasi livello (vedere la sezione Commenti). |