如何在基于清单的ETW提供程序中正确显示结构数据?

时间:2017-06-14 12:42:49

标签: xml etw

我正在使用C ++开发一个COM程序。我想使用带有清单的Windows事件跟踪(ETW)记录所有COM-Interface调用(包括传递的参数)。 由于我的程序中有数百种不同的接口方法,我希望在清单中有一个“泛型”ETW事件,我可以传递接口名称,方法名称和参数。到目前为止,这就是我对该事件的模板的样子:

<templates>
    <template tid="comInterfaceMethodCall" name="COM Interface Method Call">
        <data name="COM Object" inType="win:UnicodeString" />
        <data name="COM Interface" inType ="win:UnicodeString" />
        <data name="Interface Method" inType="win:UnicodeString" />
        <data name="Argument Count" inType="win:UInt16" />
        <struct name="Arguments" count="Argument Count" >
            <data name="Argument Name" inType="win:UnicodeString" />
            <data name="Argument Type" inType="win:UnicodeString" />
            <data name="Argument Value" inType="win:UnicodeString" />
        </struct>
        <UserData>
            <EventData xmlns="ProviderNamespace" name="COM Interface Method Call">
                <ComObject> %1 </ComObject>
                <ComInterface> %2 </ComInterface>
                <InterfaceMethod> %3 </InterfaceMethod>
                <Arguments> %5 </Arguments>
            </EventData>
        </UserData>
    </template>
</templates>

This是事件查看器中事件的样子。 如您所见,除了显示为十六进制二进制字符串的struct数据外,所有内容都正确呈现。我检查了二进制数据并且它是正确的,所以显然我正确地将数据传递给EvenWrite函数!我只想将它呈现为字符串,如清单中所述。

我已经尝试过:摆脱结构并直接提供其成员:

<data name="COM Object" inType="win:UnicodeString" />
<data name="COM Interface" inType ="win:UnicodeString" />
<data name="Interface Method" inType="win:UnicodeString" />
<data name="Argument Count" inType="win:UInt16" />
<data name="Argument Name" inType="win:UnicodeString" count="Argument Count" />
<data name="Argument Type" inType="win:UnicodeString" count="Argument Count" />
<data name="Argument Value" inType="win:UnicodeString" count="Argument Count" />

这有效,但这不是我想要的。对于具有10个参数的方法,它将首先显示10个名称,然后显示10个类型,最后显示10个值。但我希望有10个(名称,类型,值)-triples。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

在我真正回答这个问题之前,我必须指出ETW与EventLog不是一回事。这两种技术在很多方面是相互关联和协同工作的,但它们也有些独立。

ETW的核心只是一个将数据blob从生产者转移到消费者的系统。因此,可以说ET​​W支持任何类型的数据。

在核心ETW之上分层有几个框架可以帮助您对数据进行编码和解码。清单是一个这样的系统 - 清单包含对每个ETW事件所期望的数据结构的描述。根据清单,您可以生成用于打包数据的代码以创建blob。基于清单,解码工具可以解压缩blob以生成人类可读的数据表示。

EventLog是一个用于记录,存档,转发和查看重要管理事件的系统。事实上,EventLog已经存在了很长时间 - 比ETW长得多。有两种不同的方法可以将数据发送到EventLog。最初的EventLog支持基于RPC的ReportEvent API。最近,EventLog增加了对消费ETW事件的支持,即你会告诉EventLog ETW事件的重要性,EventLog会监听它们并记录它们。

您看到的问题是EventLog可以非常简单地查看事件可以包含的内容。 EventLog只能支持事件中最多99个字段的平面数组。所有与EventLog一起使用的工具都希望事件以这种方式工作。当EventLog收到ETW事件时,它必须找到一种方法使ETW事件中的数据适合简单的EventLog视图。

如果您使用ETW工具直接捕获跟踪,然后使用最新的ETW解码工具解码跟踪,您将看到更好的事件视图。但是如果您使用EventLog作为解码工具,您将看到事件的EventLog视图。