From: rob_k on
I am using the Message Compiler tool with supplied with the Win7 DDK / SDK
that is documented on MSDN
(http://msdn.microsoft.com/en-us/library/aa385638(VS.85).aspx) as being able
to produce event publishing code suitable for use in Kernel or User mode on
both XP and Vista/Win7.

The documentation states, for kernel mode I can generate publishing code with:

mc.exe <mymanifest> -km -mof

The -mof flag instructs the tool to generate code compatible with pre-Vista
OS (we are targeting XP, Vista & Windows 7) .

The resultant header file generated does contain the code to publish events
from my manifest however, there is a bug in the generated code that renders
it dysfunctional, specifically the code fills in the fields of the
EVENT_TRACE_HEADER structure without FIRST clearing out the structure with a
call to:

RtlZeroMemory(&TraceBuf.Header, sizeof(EVENT_TRACE_HEADER));

I've attached a complete snippet of the generated code below from the
1.12.7065 MC.EXE tool from the Win7 DDK.

I have also tried with version 1.12.7600 of the MC.EXE tool from the Win7
SDK - with the same results.

Below is the generated code, at the section commented "// Fill in header
fields" (where we are going into the pre-Vista codepath) you can see that the
fields of the structure are being filled in without the structure being first
cleared, if I manually insert the RtlZeroMemory call into the code after
generation and rebuild my events are raised successfully.

Without the modification the "IOWMIWriteEvent(...)" call returns 0x80000005
- or STATUS_BUFFER_OVERFLOW. Clearly this is an inconvenience to us as we had
hoped to use the tool to automatically generate / update our event publishing
code as we added new events to our solution.

--- GENERATED CODE SNIPPET ---

#ifndef MofTemplate_z_def
#define MofTemplate_z_def
ETW_INLINE
ULONG
MofTemplate_z(
__in PMCGEN_TRACE_CONTEXT Context,
__in PCEVENT_DESCRIPTOR Descriptor,
__in_opt LPCGUID Activity,
__in_opt LPCGUID EventGuid,
__in_opt PCWSTR ModuleName
)
{
#define ARGUMENT_COUNT_z 1
typedef struct _MCGEN_TRACE_BUFFER {
EVENT_TRACE_HEADER Header;
EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_z];
} MCGEN_TRACE_BUFFER;

MCGEN_TRACE_BUFFER TraceBuf;
PEVENT_DATA_DESCRIPTOR EventData = TraceBuf.EventData;

EventDataDescCreate(&EventData[0],
(ModuleName != NULL) ? ModuleName : L"NULL",
(ModuleName != NULL) ? (ULONG)((wcslen(ModuleName) +
1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));


if (!Context->McGenPreVista) {
return Context->PfnEtwWrite(Context->RegistrationHandle, Descriptor,
Activity, ARGUMENT_COUNT_z, EventData);

} else {


//
// Fill in header fields
//

TraceBuf.Header.GuidPtr = (ULONGLONG)EventGuid;
TraceBuf.Header.Flags = WNODE_FLAG_TRACED_GUID
|WNODE_FLAG_USE_GUID_PTR|WNODE_FLAG_USE_MOF_PTR;
TraceBuf.Header.Class.Version = (USHORT)Descriptor->Version;
TraceBuf.Header.Class.Level = Descriptor->Level;
TraceBuf.Header.Class.Type = Descriptor->Opcode;
TraceBuf.Header.Size = sizeof(MCGEN_TRACE_BUFFER);

((PWNODE_HEADER)&(TraceBuf.Header))->HistoricalContext = Context->Logger;
return IoWMIWriteEvent(&TraceBuf.Header);
}
}
#endif