zoukankan      html  css  js  c++  java
  • Windows ETW 学习与使用三

    一、注册一个ETW

    1.使用EventRegister注册一个ETW,使用EventWrite写入事件

    Writing Manifest-based Events

    // WritingManifestbasedEvents.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    
    #include <windows.h>
    #include <stdio.h>
    #include <evntprov.h>
    //#include "provider.h"  // Generated from manifest
    
    //**********************************************************************`
    //* This is an include file generated by Message Compiler.             *`
    //*                                                                    *`
    //* Copyright (c) Microsoft Corporation. All Rights Reserved.          *`
    //**********************************************************************`
    #pragma once
    //+
    // Provider Microsoft-Windows-ETWProvider Event Count 1
    //+
    EXTERN_C __declspec(selectany) const GUID ProviderGuid = {0xd8909c24, 0x5be9, 0x4502, {0x98, 0xca, 0xab, 0x7b, 0xdc, 0x24, 0x89, 0x9d}};
    //
    // Keyword
    //
    #define READ_KEYWORD 0x1
    #define WRITE_KEYWORD 0x2
    #define LOCAL_KEYWORD 0x4
    #define REMOTE_KEYWORD 0x8
    
    //
    // Event Descriptors
    //
    EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR TransferEvent = {0x1, 0x0, 0x0, 0x4, 0x0, 0x0, 0x5};
    #define TransferEvent_value 0x1
    #define MSG_Provider_Name                    0x90000001L
    #define MSG_Event_WhenToTransfer             0xB0000001L
    #define MSG_Map_Download                     0xD0000001L
    #define MSG_Map_Upload                       0xD0000002L
    #define MSG_Map_UploadReply                  0xD0000003L
    #define MSG_Map_Sunday                       0xF0000001L
    #define MSG_Map_Monday                       0xF0000002L
    #define MSG_Map_Tuesday                      0xF0000003L
    #define MSG_Map_Wednesday                    0xF0000004L
    #define MSG_Map_Thursday                     0xF0000005L
    #define MSG_Map_Friday                       0xF0000006L
    #define MSG_Map_Saturday                     0xF0000007L
    
    #define SUNDAY     0X1
    #define MONDAY     0X2
    #define TUESDAY    0X4
    #define WEDNESDAY  0X8
    #define THURSDAY   0X10
    #define FRIDAY     0X20
    #define SATURDAY   0X40
    
    enum TRANSFER_TYPE {
        Download = 1,
        Upload,
        UploadReply
    };
    
    #define MAX_NAMEDVALUES          5  // Maximum array size
    #define MAX_PAYLOAD_DESCRIPTORS  9 + (2 * MAX_NAMEDVALUES)
    
    typedef struct _namedvalue {
        LPWSTR name;
        USHORT value;
    } NAMEDVALUE, *PNAMEDVALUE;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        DWORD status = ERROR_SUCCESS;
        REGHANDLE RegistrationHandle = NULL; 
        EVENT_DATA_DESCRIPTOR Descriptors[MAX_PAYLOAD_DESCRIPTORS]; 
        DWORD i = 0;
    
        // Data to load into event descriptors
    
        USHORT Scores[3] = {45, 63, 21};
        ULONG pImage = (ULONG)&Scores;
        DWORD TransferType = Upload;
        DWORD Day = MONDAY | TUESDAY;
        LPWSTR Path = L"c:\path\folder\file.ext";
        BYTE Cert[11] = {0x2, 0x4, 0x8, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x0, 0x1};
        PBYTE Guid = (PBYTE) &ProviderGuid;
        USHORT ArraySize = MAX_NAMEDVALUES;
        BOOL IsLocal = TRUE;
        NAMEDVALUE NamedValues[MAX_NAMEDVALUES] = { 
            {L"Bill", 1},
            {L"Bob", 2},
            {L"William", 3},
            {L"Robert", 4},
            {L"", 5}
        };
    
        status = EventRegister(
            &ProviderGuid,      // GUID that identifies the provider
            NULL,               // Callback not used
            NULL,               // Context noot used
            &RegistrationHandle // Used when calling EventWrite and EventUnregister
            );
    
        if (ERROR_SUCCESS != status)
        {
            wprintf(L"EventRegister failed with %lu
    ", status);
            goto cleanup;
        }
    
        // Load the array of data descriptors for the TransferEvent event. 
        // Add the data to the array in the order of the <data> elements
        // defined in the event's template. 
    
        EventDataDescCreate(&Descriptors[i++], &pImage, sizeof(ULONG));
        EventDataDescCreate(&Descriptors[i++], Scores, sizeof(Scores));
        EventDataDescCreate(&Descriptors[i++], Guid, sizeof(GUID));
        EventDataDescCreate(&Descriptors[i++], Cert, sizeof(Cert));
        EventDataDescCreate(&Descriptors[i++], &IsLocal, sizeof(BOOL));
        EventDataDescCreate(&Descriptors[i++], Path, (ULONG)(wcslen(Path) + 1) * sizeof(WCHAR));
        EventDataDescCreate(&Descriptors[i++], &ArraySize, sizeof(USHORT));
    
        // If your event contains a structure, you should write each member
        // of the structure separately. If the structure contained integral data types
        // such as DWORDs and the data types were aligned on an 8-byte boundary, you 
        // could use the following call to write the structure, however, you are 
        // encouraged to write the members separately.
        //
        // EventDataDescCreate(&EvtData, struct, sizeof(struct));
        //
        // Because the array of structures in this example contains both strings 
        // and numbers, you must write each member of the structure separately.
    
        for (int j = 0; j < MAX_NAMEDVALUES; j++)
        {
            EventDataDescCreate(&Descriptors[i++], NamedValues[j].name, (ULONG)(wcslen(NamedValues[j].name)+1) * sizeof(WCHAR) );
            EventDataDescCreate(&Descriptors[i++], &(NamedValues[j].value), sizeof(USHORT) );
        }
    
        EventDataDescCreate(&Descriptors[i++], &Day, sizeof(DWORD));
        EventDataDescCreate(&Descriptors[i++], &TransferType, sizeof(DWORD));
    
        // Write the event. You do not have to verify if your provider is enabled before
        // writing the event. ETW will write the event to any session that enabled
        // the provider. If no session enabled the provider, the event is not 
        // written. If you need to perform extra work to write an event that you
        // would not otherwise do, you may want to call the EventEnabled function
        // before performing the extra work. The EventEnabled function tells you if a
        // session has enabled your provider, so you know if you need to perform the 
        // extra work or not.
    
        status = EventWrite(
            RegistrationHandle,              // From EventRegister
            &TransferEvent,                  // EVENT_DESCRIPTOR generated from the manifest
            (ULONG)MAX_PAYLOAD_DESCRIPTORS,  // Size of the array of EVENT_DATA_DESCRIPTORs
            &Descriptors[0]                  // Array of descriptors that contain the event data
        );
    
        if (status != ERROR_SUCCESS) 
        {
            wprintf(L"EventWrite failed with 0x%x", status);
        }
    
    cleanup:
    
        EventUnregister(RegistrationHandle);
    
        getchar();
        return 0;
    }

    目前该方案,可以用前面的基础知识,传入ProviderGuid来进行解析,数据在pEvent->UserData中

    typedef struct _EVENT_RECORD {
    
        EVENT_HEADER        EventHeader;            // Event header
        ETW_BUFFER_CONTEXT  BufferContext;          // Buffer context
        USHORT              ExtendedDataCount;      // Number of extended
                                                    // data items
        USHORT              UserDataLength;         // User data length
        PEVENT_HEADER_EXTENDED_DATA_ITEM            // Pointer to an array of 
                            ExtendedData;           // extended data items                                               
        PVOID               UserData;               // Pointer to user data
        PVOID               UserContext;            // Context from OpenTrace
    } EVENT_RECORD, *PEVENT_RECORD; 

    2.发布一个ETW

    Developing-a-Provider

    Publishing Your Event Schema for a Manifest-based Provider

    <!-- <?xml version="1.0" encoding="UTF-16"?> -->
    <instrumentationManifest
        xmlns="http://schemas.microsoft.com/win/2004/08/events" 
        xmlns:win="https://manifests.microsoft.com/win/2004/08/windows/events"
        xmlns:xs="https://www.w3.org/2001/XMLSchema"    
        >
    
        <instrumentation>
            <events>
    
                <provider name="Microsoft-Windows-ETWProvider" 
                    guid="{D8909C24-5BE9-4502-98CA-AB7BDC24899D}" 
                    symbol="ProviderGuid" 
                    resourceFileName="c:codeetwv2providerdebugv2provider.exe" 
                    messageFileName="c:codeetwv2providerdebugv2provider.exe"
                    message="$(string.Provider.Name)"
                    >
    
                    <keywords>
                        <keyword name="Read" symbol="READ_KEYWORD" mask="0x1" />
                        <keyword name="Write" symbol="WRITE_KEYWORD" mask="0x2" />
                        <keyword name="Local" symbol="LOCAL_KEYWORD" mask="0x4" />
                        <keyword name="Remote" symbol="REMOTE_KEYWORD" mask="0x8" />
                    </keywords>
    
                    <maps>
                        <valueMap name="TransferType">
                            <map value="1" message="$(string.Map.Download)"/>
                            <map value="2" message="$(string.Map.Upload)"/>
                            <map value="3" message="$(string.Map.UploadReply)"/>
                        </valueMap>
    
                        <bitMap name="DaysOfTheWeek">
                            <map value="0x1" message="$(string.Map.Sunday)"/>
                            <map value="0x2" message="$(string.Map.Monday)"/>
                            <map value="0x4" message="$(string.Map.Tuesday)"/>
                            <map value="0x8" message="$(string.Map.Wednesday)"/>
                            <map value="0x10" message="$(string.Map.Thursday)"/>
                            <map value="0x20" message="$(string.Map.Friday)"/>
                            <map value="0x40" message="$(string.Map.Saturday)"/>
                        </bitMap>
                    </maps>
    
                    <templates>
    
                       <template tid="TransferTemplate">
                            <data name="Image" inType="win:Pointer"/>
                            <data name="Scores" inType="win:UInt16" count="3"/>
                            <data name="ID" inType="win:GUID"/>
                            <data name="Certificate" inType="win:Binary" length="11" />
                            <data name="IsLocal" inType="win:Boolean" />
                            <data name="Path" inType="win:UnicodeString" />
    
                            <data name="ValuesCount" inType="win:UInt16" />
                            <struct name="Values" count="ValuesCount" >
                                <data name="Name" inType="win:UnicodeString" />
                                <data name="Value" inType="win:UInt16" />
                            </struct>
    
                            <data name="Day" inType="win:UInt32" map="DaysOfTheWeek"/>
                            <data name="Transfer" inType="win:UInt32" map="TransferType"/>
    
                            <UserData>
                                <EventData xmlns="ProviderNamespace">
                                    <Transfer> %10 </Transfer>
                                    <Day> %9 </Day>
                                    <ValuesCount> %7 </ValuesCount>
                                    <Values> %8 </Values>
                                    <Path> %6 </Path>
                                    <IsLocal> %5 </IsLocal>
                                    <Scores> %2 </Scores>
                                    <Image> %1 </Image>
                                    <Certificate> %4 </Certificate>
                                    <ID> %3 </ID>
                                </EventData>
                            </UserData>
                        </template>
    
                    </templates>
    
                    <events>
                        <event value="1" 
                            level="win:Informational" 
                            template="TransferTemplate" 
                            symbol="TransferEvent"
                            message ="$(string.Event.WhenToTransfer)"
                            keywords="Read Local" />
                    </events>
    
    
                </provider>
    
            </events>
    
        </instrumentation>
    
        <localization>
            <resources culture="en-US">
                <stringTable>
    
                    <string id="Provider.Name" value="Microsoft-Windows-ETWProvider"/>
    
                    <string id="Map.Download" value="Download"/>
                    <string id="Map.Upload" value="Upload"/>
                    <string id="Map.UploadReply" value="Upload-reply"/> 
    
                    <string id="Map.Sunday" value="Sunday"/>
                    <string id="Map.Monday" value="Monday"/>
                    <string id="Map.Tuesday" value="Tuesday"/>
                    <string id="Map.Wednesday" value="Wednesday"/>
                    <string id="Map.Thursday" value="Thursday"/>
                    <string id="Map.Friday" value="Friday"/>
                    <string id="Map.Saturday" value="Saturday"/>
    
                    <string id="Event.WhenToTransfer" value="The %10 transfer will occur %9."/>
    
                </stringTable>
            </resources>
        </localization>
    
    </instrumentationManifest>

     具体如何使用xml可以参考UIForETW项目的ETWProviders.dll编写

  • 相关阅读:
    Android 下拉刷新之ScrollView--PullToRefreshScrollView
    Android 将Openfire中的MUC改造成类似QQ群一样的永久群
    Android多行文本折叠展开效果
    Android关于实现EditText中加多行下划线的的一种方法
    Android 官方下拉刷新组件SwipeRefreshLayout
    listview滑动顶部停靠(stickyListHeadersListView)
    Hadoop HBase概念学习系列之优秀行键设计(十六)
    Hadoop HBase概念学习系列之HBase里的长表VS宽表VS窄表(十五)
    Hadoop HBase概念学习系列之HBase里的客户端和HBase集群建立连接(详细)(十四)
    Hadoop HBase概念学习系列之HBase表的一些设置(强烈推荐好好领悟)(十三)
  • 原文地址:https://www.cnblogs.com/aliflycoris/p/13863306.html
Copyright © 2011-2022 走看看