Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tato část popisuje, jak pomocí rozhraní API pro trasování událostí pro Windows (ETW) přidat trasování událostí do ovladačů režimu jádra. Rozhraní API režimu jádra ETW bylo zavedeno ve Windows Vista a není podporováno na starších operačních systémech. Pokud váš ovladač potřebuje podporovat funkce trasování v systémech Windows 2000 a novějších, použijte WPP Software Tracing nebo trasování událostí rozhraní WMI.
Návod
Chcete-li zobrazit Ukázkový kód, který ukazuje, jak implementovat ETW (Trasování událostí) pomocí sady Windows Driver Kit (WDK) a Visual Studio, podívejte se na ukázku Eventdrv.
V této části:
Pracovní postup – přidání trasování událostí do ovladačů Kernel-Mode
1. Rozhodněte typ událostí, které mají být vyvolání a kde je publikovat.
2. Vytvoření manifestu instrumentace, který definuje poskytovatele, události a kanály
3. Zkompilujte manifest instrumentace pomocí kompilátoru zpráv (Mc.exe)
7. Otestujte ovladač a ověřte podporu pro ETW.
Pracovní postup – přidání trasování událostí do ovladačů Kernel-Mode
1. Rozhodněte typ událostí, které mají být vyvolání a kde je publikovat.
Než začnete psát kód, musíte se rozhodnout, jaký typ událostí má ovladač protokolovat prostřednictvím trasování událostí pro Windows (ETW). Můžete například chtít protokolovat události, které vám pomůžou diagnostikovat problémy po distribuci ovladače nebo události, které vám můžou pomoct při vývoji ovladače. Informace najdete v tématu Referenční informace k protokolu událostí systému Windows.
Typy událostí jsou identifikovány pomocí kanálů. Kanál je pojmenovaný stream událostí typu Admin, Operational, Analytical nebo Debug směrovaný na konkrétní cílovou skupinu, podobně jako televizní kanál. Kanál doručuje události od poskytovatele událostí do protokolů událostí a příjemců událostí. Informace naleznete v tématu Definování kanálů.
Během vývoje vás s největší pravděpodobností zajímá trasování událostí, které vám pomůžou ladit kód. Stejný kanál je možné použít v produkčním kódu, který vám pomůže vyřešit problémy, které se můžou objevit po nasazení ovladače. Můžete také chtít sledovat události, které lze použít k měření výkonu; tyto události můžou it specialistům pomoct vyladit výkon serveru a můžou pomoct identifikovat kritické body sítě.
2. Vytvoření manifestu instrumentace, který definuje poskytovatele, události a kanály
Manifest instrumentace je soubor XML, který poskytuje formální popis událostí, které poskytovatel vyvolá. Manifest instrumentace identifikuje zprostředkovatele událostí, určuje kanál nebo kanály (až osm) a popisuje události a šablony, které události používají. Manifest instrumentace navíc umožňuje lokalizaci řetězců, abyste mohli lokalizovat zprávy trasování. Systém událostí a příjemci událostí můžou k provádění dotazů a analýzy využít strukturovaná data XML poskytnutá v manifestu.
Informace o manifestu instrumentace naleznete v tématu Zápis manifestu instrumentace (Windows), EventManifest Schema (Windows) a Použití protokolu událostí systému Windows (Windows).
Následující manifest instrumentace ukazuje zprostředkovatele událostí, který používá název "Ukázkový ovladač". Všimněte si, že tento název nemusí být stejný jako název binárního souboru ovladače. Manifest také určuje identifikátor GUID pro zprostředkovatele a cesty k zprávám a souborům prostředků. Soubory se zprávami a prostředky umožňují ETW zjistit, kde jsou umístěny prostředky potřebné k dekódování a hlášení událostí. Tyto cesty ukazují na umístění souboru ovladače (.sys). Ovladač musí být nainstalován v zadaném adresáři v cílovém počítači.
Příklad používá pojmenovaný kanál System, kanál pro události typu Admin. Tento kanál je definován v souboru Winmeta.xml, který je součástí sady Windows Driver Kit (WDK) v adresáři%WindowsSdkDir%\include\um.
Kanál System je zabezpečený pro aplikace spuštěné v rámci účtů systémových služeb. Manifest obsahuje šablony událostí popisující typy dat zadaných s událostmi při jejich publikování spolu s jejich statickým a dynamickým obsahem. Tento ukázkový manifest definuje tři události: StartEvent, SampleEventAa UnloadEvent.
Kromě kanálů můžete události přidružit k úrovním a klíčovým slovům. Klíčová slova a úrovně poskytují způsob, jak povolit události a poskytnout mechanismus filtrování událostí při jejich publikování. Klíčová slova se dají použít k seskupení logicky souvisejících událostí. Úroveň lze použít k označení závažnosti nebo podrobností události, například kritické, chybové, upozornění nebo informační. Soubor Winmeta.xml obsahuje předdefinované hodnoty atributů událostí.
Při vytváření šablony pro datovou část události (zpráva události a data) musíte zadat vstupní a výstupní typy. Podporované typy jsou popsány v části Poznámky komplexního typu InputType (Windows).
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<instrumentationManifest
xmlns="http://schemas.microsoft.com/win/2004/08/events"
xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd"
>
<instrumentation>
<events>
<provider
guid="{b5a0bda9-50fe-4d0e-a83d-bae3f58c94d6}"
messageFileName="%SystemDrive%\ETWDriverSample\Eventdrv.sys"
name="Sample Driver"
resourceFileName="%SystemDrive%\ETWDriverSample\Eventdrv.sys"
symbol="DriverControlGuid"
>
<channels>
<importChannel
chid="SYSTEM"
name="System"
/>
</channels>
<templates>
<template tid="tid_load_template">
<data
inType="win:UInt16"
name="DeviceNameLength"
outType="xs:unsignedShort"
/>
<data
inType="win:UnicodeString"
name="name"
outType="xs:string"
/>
<data
inType="win:UInt32"
name="Status"
outType="xs:unsignedInt"
/>
</template>
<template tid="tid_unload_template">
<data
inType="win:Pointer"
name="DeviceObjPtr"
outType="win:HexInt64"
/>
</template>
</templates>
<events>
<event
channel="SYSTEM"
level="win:Informational"
message="$(string.StartEvent.EventMessage)"
opcode="win:Start"
symbol="StartEvent"
template="tid_load_template"
value="1"
/>
<event
channel="SYSTEM"
level="win:Informational"
message="$(string.SampleEventA.EventMessage)"
opcode="win:Info"
symbol="SampleEventA"
value="2"
/>
<event
channel="SYSTEM"
level="win:Informational"
message="$(string.UnloadEvent.EventMessage)"
opcode="win:Stop"
symbol="UnloadEvent"
template="tid_unload_template"
value="3"
/>
</events>
</provider>
</events>
</instrumentation>
<localization xmlns="http://schemas.microsoft.com/win/2004/08/events">
<resources culture="en-US">
<stringTable>
<string
id="StartEvent.EventMessage"
value="Driver Loaded"
/>
<string
id="SampleEventA.EventMessage"
value="IRP A Occurred"
/>
<string
id="UnloadEvent.EventMessage"
value="Driver Unloaded"
/>
</stringTable>
</resources>
</localization>
</instrumentationManifest>
3. Zkompilujte manifest instrumentace pomocí kompilátoru zpráv (Mc.exe)
Před kompilací zdrojového kódu musí být spuštěn kompilátor zpráv (Mc.exe). Kompilátor zpráv je součástí sady Windows Driver Kit (WDK). Kompilátor zpráv vytvoří soubor hlaviček, který obsahuje definice pro zprostředkovatele událostí, atributy událostí, kanály a události. Tento soubor hlaviček musíte zahrnout do zdrojového kódu. Kompilátor zpráv také umístí vygenerovaný skript kompilátoru prostředků (*.rc) a vygenerované soubory .bin (binární prostředky), které obsahuje skript kompilátoru prostředků.
Tento krok můžete zahrnout jako součást procesu sestavení několika způsoby:
Přidání úlohy kompilátoru zpráv do souboru projektu ovladače (jak je znázorněno v ukázce Eventdrv).
Pomocí sady Visual Studio přidáte manifest instrumentace a nakonfigurujete vlastnosti kompilátoru zpráv.
Přidání úlohy kompilátoru zpráv do souboru projektu Příklad zahrnutí kompilátoru zpráv do procesu sestavení najdete v souboru projektu ukázky Eventdrv. V souboru Eventdrv.vcxproj existuje <část MessageCompile> , která volá kompilátor zpráv. Kompilátor zpráv používá jako vstup soubor manifestu (evntdrv.xml) k vygenerování souboru hlavičky evntdrvEvents.h. Tato část také určuje cesty pro vygenerované soubory RC a povolí makra protokolování režimu jádra. Tento oddíl můžete zkopírovat a přidat ho do souboru projektu ovladače (.vcxproj).
<MessageCompile Include="evntdrv.xml">
<GenerateKernelModeLoggingMacros>true</GenerateKernelModeLoggingMacros>
<HeaderFilePath>.\$(IntDir)</HeaderFilePath>
<GeneratedHeaderPath>true</GeneratedHeaderPath>
<WinmetaPath>"$(SDK_INC_PATH)\winmeta.xml"</WinmetaPath>
<RCFilePath>.\$(IntDir)</RCFilePath>
<GeneratedRCAndMessagesPath>true</GeneratedRCAndMessagesPath>
<GeneratedFilesBaseName>evntdrvEvents</GeneratedFilesBaseName>
<UseBaseNameOfInput>true</UseBaseNameOfInput>
</MessageCompile>
Když sestavíte ukázku Eventdrv.sys, Visual Studio vytvoří potřebné soubory pro trasování událostí. Také přidá manifest evntdrv.xml do seznamu souborů prostředků pro projekt ovladače. Manifest můžete vybrat a podržet (nebo na něj kliknout pravým tlačítkem myši) a zobrazit stránky vlastností kompilátoru zpráv.
Přidání manifestu instrumentace pomocí sady Visual Studio
Do projektu ovladače můžete přidat manifest instrumentace a potom nakonfigurovat vlastnosti kompilátoru zpráv tak, aby se sestavily potřebné soubory prostředků a hlaviček.
Přidání manifestu instrumentace do projektu pomocí sady Visual Studio
V Průzkumníku řešení přidejte soubor manifestu do projektu ovladače. Vyberte a podržte (nebo klikněte pravým tlačítkem) Soubory prostředků > Přidat > existující položku (například evntdrv.xml nebo mydriver.man).
Vyberte a podržte (nebo klikněte pravým tlačítkem myši) soubor, který jste právě přidali, a pomocí stránek vlastností změňte typ položky na MessageCompile a vyberte Použít.
Zobrazí se vlastnosti kompilátoru zpráv. V části Obecné nastavte následující možnosti a pak vyberte Použít.
Obecné Nastavení Vytváření maker pro protokolování v režimu jádra Ano (-km) Použít základní název vstupu Ano (-b) V části Možnosti souboru nastavte následující možnosti a pak vyberte Použít.
Možnosti souboru Nastavení Vygenerujte soubor hlaviček, který obsahuje čítač Ano Cesta k souboru záhlaví $(IntDir) Vygenerovaná rc a cesta k binárním souborům zpráv Ano Cesta k souboru RC $(IntDir) Vygenerovaný základní název souborů $(Název souboru)
Ve výchozím nastavení používá kompilátor zpráv základní název vstupního souboru jako základní název souborů, které generuje. Chcete-li zadat základní název, nastavte pole Generated Files Base Name (-z). V ukázce Eventdr.sys je základní název nastaven na evntdrvEvents tak, aby odpovídal názvu souboru hlavičky evntdrvEvents.h, který je součástí evntdrv.c.
Poznámka:
Pokud do projektu sady Visual Studio nezahrnete vygenerovaný soubor .rc, mohou se při instalaci souboru manifestu zobrazit chybové zprávy o prostředcích, které nebyly nalezeny.
4. Přidejte vygenerovaný kód pro vyvolání (publikování) událostí (registrace, zrušení registrace a zápis událostí)
V manifestu instrumentace jste definovali názvy zprostředkovatele události a popisovače událostí. Když zkompilujete manifest instrumentace pomocí kompilátoru zpráv, kompilátor zpráv vygeneruje hlavičkový soubor popisující prostředky a také definuje makra pro události. Teď musíte do ovladače přidat vygenerovaný kód, aby se tyto události vyvolaly.
Do zdrojového souboru zahrňte soubor hlavičky události, který je vytvořen kompilátorem zpráv (MC.exe). Například v ukázce Eventdrv zdrojový soubor Evntdrv.c obsahuje hlavičkový soubor (evntdrvEvents.h), který byl vygenerován v předchozím kroku:
#include "evntdrvEvents.h"Přidejte makra, která registrují a zruší registraci ovladače jako zprostředkovatele událostí. Například v souboru hlaviček pro ukázku Eventdrv (evntdrvEvents.h) kompilátor zpráv vytvoří makra na základě názvu zprostředkovatele. V manifestu používá ukázka Eventdrv název "Sample Driver" jako název zprostředkovatele. Kompilátor zpráv zkombinuje název zprostředkovatele s makrem události a zaregistruje zprostředkovatele v tomto případě EventRegisterSample_Driver.
// This is the generated header file envtdrvEvents.h // // ... // // // Register with ETW Vista + // #ifndef EventRegisterSample_Driver #define EventRegisterSample_Driver() McGenEventRegister(&DriverControlGuid, McGenControlCallbackV2, &DriverControlGuid_Context, &Sample_DriverHandle) #endifPřidejte makro EventRegister<zprostředkovatele> do funkce DriverEntry. Přidejte tuto funkci za kód, který vytvoří a inicializuje objekt zařízení. Všimněte si, že volání funkce EventRegister<zprostředkovatele> musí být spárováno s voláním funkce EventUnregister<zprostředkovatele>. Můžete odregistrovat ovladač ve své rutině Uvolnění*.
// DriverEntry function // ... // Register with ETW // EventRegisterSample_Driver();Přidejte vygenerovaný kód do zdrojových souborů ovladače pro zápis (vyvolání) událostí zadaných v manifestu. Soubor hlaviček, který jste zkompilovali z manifestu, obsahuje vygenerovaný kód pro ovladač. Pomocí funkcí EventWrite<událostí> definovaných v souboru hlaviček publikujte trasovací zprávy do ETW. Například následující kód ukazuje makra pro události definované v evntdrvEvents.h pro ukázku Eventdrv.
Makra pro zápis těchto událostí se nazývají:
EventWriteStartEvent,EventWriteSampleEventAaEventWriteUnloadEvent. Jak vidíte v definici těchto maker, definice makra automaticky zahrnuje makro EventEnabled<události>, které kontroluje, zda je událost povolena. Ověření eliminuje potřebu vytvoření datové části, pokud není událost aktivována./// // This is the generated header file envtdrvEvents.h // // ... // // Enablement check macro for StartEvent // #define EventEnabledStartEvent() ((Sample_DriverEnableBits[0] & 0x00000001) != 0) // // Event Macro for StartEvent // #define EventWriteStartEvent(Activity, DeviceNameLength, name, Status)\ EventEnabledStartEvent() ?\ Template_hzq(Sample_DriverHandle, &StartEvent, Activity, DeviceNameLength, name, Status)\ : STATUS_SUCCESS\ // // Enablement check macro for SampleEventA // #define EventEnabledSampleEventA() ((Sample_DriverEnableBits[0] & 0x00000001) != 0) // // Event Macro for SampleEventA // #define EventWriteSampleEventA(Activity)\ EventEnabledSampleEventA() ?\ TemplateEventDescriptor(Sample_DriverHandle, &SampleEventA, Activity)\ : STATUS_SUCCESS\ // // Enablement check macro for UnloadEvent // #define EventEnabledUnloadEvent() ((Sample_DriverEnableBits[0] & 0x00000001) != 0) // // Event Macro for UnloadEvent // #define EventWriteUnloadEvent(Activity, DeviceObjPtr)\ EventEnabledUnloadEvent() ?\ Template_p(Sample_DriverHandle, &UnloadEvent, Activity, DeviceObjPtr)\ : STATUS_SUCCESS\Přidejte makra EventWrite<události> do zdrojového kódu pro události, které vyvoláváte. Například následující fragment kódu ukazuje rutinu DriverEntry z ukázky Eventdrv. DriverEntry obsahuje makra pro registraci ovladače ve službě ETW (EventRegisterSample_Driver) a makro pro zápis události ovladače do etW (EventWriteStartEvent).
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++ Routine Description: Installable driver initialization entry point. This entry point is called directly by the I/O system. Arguments: DriverObject - pointer to the driver object RegistryPath - pointer to a unicode string representing the path to driver-specific key in the registry Return Value: STATUS_SUCCESS if successful STATUS_UNSUCCESSFUL otherwise --*/ { NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING DeviceName; UNICODE_STRING LinkName; PDEVICE_OBJECT EventDrvDeviceObject; WCHAR DeviceNameString[128]; ULONG LengthToCopy = 128 * sizeof(WCHAR); UNREFERENCED_PARAMETER (RegistryPath); KdPrint(("EventDrv: DriverEntry\n")); // // Create Dispatch Entry Points. // DriverObject->DriverUnload = EventDrvDriverUnload; DriverObject->MajorFunction[ IRP_MJ_CREATE ] = EventDrvDispatchOpenClose; DriverObject->MajorFunction[ IRP_MJ_CLOSE ] = EventDrvDispatchOpenClose; DriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL ] = EventDrvDispatchDeviceControl; RtlInitUnicodeString( &DeviceName, EventDrv_NT_DEVICE_NAME ); // // Create the Device object // Status = IoCreateDevice( DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &EventDrvDeviceObject); if (!NT_SUCCESS(Status)) { return Status; } RtlInitUnicodeString( &LinkName, EventDrv_WIN32_DEVICE_NAME ); Status = IoCreateSymbolicLink( &LinkName, &DeviceName ); if ( !NT_SUCCESS( Status )) { IoDeleteDevice( EventDrvDeviceObject ); return Status; } // // Choose a buffering mechanism // EventDrvDeviceObject->Flags |= DO_BUFFERED_IO; // // Register with ETW // EventRegisterSample_Driver(); // // Log an Event with : DeviceNameLength // DeviceName // Status // // Copy the device name into the WCHAR local buffer in order // to place a NULL character at the end, since this field is // defined in the manifest as a NULL-terminated string if (DeviceName.Length <= 128 * sizeof(WCHAR)) { LengthToCopy = DeviceName.Length; } RtlCopyMemory(DeviceNameString, DeviceName.Buffer, LengthToCopy); DeviceNameString[LengthToCopy/sizeof(WCHAR)] = L'\0'; EventWriteStartEvent(NULL, DeviceName.Length, DeviceNameString, Status); return STATUS_SUCCESS; }
Přidejte všechny makra EventWrite<událostí> do zdrojového kódu pro události, které vyvoláváte. Ukázku Eventdrv si můžete prohlédnout a podívat se, jak se ostatní dvě makra volají pro události ve zdrojovém kódu ovladače.
Zrušte registraci ovladače jako zprostředkovatele událostí pomocí makra EventUnregister<provider> z vygenerovaného hlavičkového souboru.
Toto volání funkce umístěte do rutiny uvolnění ovladače. Po zavolání makra EventUnregister<zprostředkovatele> by se neměla provádět žádná volání trasování. Neschopnost zrušit registraci zprostředkovatele událostí může způsobit chyby při uvolnění procesu, protože jakékoli callbackové funkce přidružené k procesu již nejsou platné.
// DriverUnload function // ... // // Unregister the driver as an ETW provider // EventUnregisterSample_Driver();
5. Sestavení ovladače
Pokud jste do projektu přidali manifest nástroje a nakonfigurovali vlastnosti kompilátoru zpráv (MC.exe), můžete vytvořit projekt nebo řešení ovladače pomocí Visual Studio a MSBuild.
Otevřete řešení ovladače v sadě Visual Studio.
Sestavte projekt z nabídky Sestavení výběrem možnosti Sestavit řešení. Další informace o vytváření řešení naleznete v tématu Sestavení ovladače.
6. Instalace manifestu
Manifest je nutné nainstalovat do cílového systému, aby příjemci událostí (například protokol událostí) mohli najít umístění binárního souboru, který obsahuje metadata události. Pokud jste do projektu ovladače v kroku 3 přidali úlohu kompilátoru zpráv, zkompiloval se manifest instrumentace a soubory prostředků se vygenerovaly při sestavení ovladače. K instalaci manifestu použijte nástroj příkazového řádku události systému Windows (Wevtutil.exe). Syntaxe instalace manifestu je následující:
wevtutil.exe imdrivermanifest
Pokud chcete například nainstalovat manifest pro ukázkový ovladač Evntdrv.sys, otevřete okno příkazového řádku se zvýšenými oprávněními (Spustit jako správce) přejděte do adresáře, kde se nachází soubor evntdrv.xml, a zadejte následující příkaz:
Wevtutil.exe im evntdrv.xml
Po dokončení relace trasování odinstalujte manifest pomocí následující syntaxe.
wevtutil.exe umdrivermanifest
Například odinstalace manifestu pro ukázku Eventdrv:
Wevtutil.exe um evntdrv.xml
7. Otestujte ovladač a ověřte podporu ETW.
Nainstalujte ovladač. Cvičením ovladače vygenerujte aktivitu trasování. Prohlédněte si výsledky v Prohlížeči událostí. Můžete také spustit Tracelog a pak spustit Tracerpt, nástroj pro zpracování protokolů trasování událostí, řídit, shromažďovat a zobrazovat protokoly trasování událostí.