Event Log Samples (Compact 2013)

3/28/2014

The following event log samples illustrate possible implementations of the following:

  • Event log manifest
  • Event log provider
  • Event log subscriber

Sample Manifest

Applications and DLLs use an instrumentation manifest to identify their instrumentation providers and the events that the providers write.

For more information about how to set up your instrumentation manifest, see Identifying the Provider and Compiling an Instrumentation Manifest on MSDN.

The following code example shows a sample manifest that sets up a publisher and events to publish.

<!-- <?xml version="1.0" encoding="UTF-16"?> -->

<instrumentationManifest
   xmlns="https://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">
   <instrumentation>
      <events>
         <!--Publisher Info -->
         <provider name="Microsoft-WindowsCE-EventLogSamplePublisher"
            guid="{1db28f3f-8f80-4027-8c5a-a11f7f10f62d}"
            symbol="WINDOWSCE_EVENTLOG_SAMPLE_PUBLISHER"
            resourceFileName="Publisher.exe"
            messageFileName="Publisher.exe">
            <!--Channel to which this Publisher can publish -->
            <channels>
               <!--Pre-Existing channel can be imported, but not required. -->
               <importChannel chid="C1" name="Application"/>
               <!--New Channel can be declared for this Publisher-->
               <channel chid="MyChannel"
                  name="Microsoft-WindowsCE-EventLogSamplePublisher-Operational"
                  type="Operational"
                  symbol="SAMPLE_PUBLISHER"
                  enabled="true"
                  value="189"/>
                 
               </channels>
               <!--Event Templates -->
               <templates>
                  <template tid="MyEventTemplate">
                     <data name="Prop_UnicodeString" inType="win:UnicodeString" />
                     <data name="Prop_UInt32" inType="win:UInt32" />
                     <UserData>
                        <MyEvent2 xmlns="myNs">
                           <Prop_UnicodeString> %1 </Prop_UnicodeString>
                           <Prop_UInt32> %2 </Prop_UInt32>
                        </MyEvent2>
                     </UserData>
                  </template>
               </templates>
               <!--All the Events that can be published by this Publisher -->
               <events>
                  <event value="1"
                     level="win:Informational"
                     template="MyEventTemplate"
                     channel="MyChannel"
                     symbol="PROCESS_SAMPLE_EVENT"
                     message="$(string.Publisher.EventMessage)"/>
               </events>
            </provider>
       </events>
   </instrumentation>
   <localization>
      <resources culture="en-US">
         <stringTable>
            <!--This is how event data can be used as part of a message string -->
            <string id="Publisher.EventMessage"
               value="Prop_UnicodeString=%1;%n
                  Prop_UInt32=%2;%n"/>
         </stringTable>
      </resources>
   </localization>
</instrumentationManifest><!-- <?xml version="1.0" encoding="UTF-16"?> -->
<instrumentationManifest
   xmlns="https://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">
   <instrumentation>
      <events>
         <!--Publisher Info -->
         <provider name="Microsoft-WindowsCE-EventLogSamplePublisher"
            guid="{1db28f3f-8f80-4027-8c5a-a11f7f10f62d}"
            symbol="WINDOWSCE_EVENTLOG_SAMPLEPUBLISHER"
            resourceFileName="C:\temp\Publisher.exe"
            messageFileName="C:\temp\Publisher.exe">
            <!--Channel to which this Publisher can publish -->
            <channels>
               <!--Pre-Existing channel can be imported, but not required. -->
               <importChannel chid="C1" name="Application"/>
               <!--New Channel can be declared for this Publisher-->
               <channel chid="MyChannel"
                  name="Microsoft-WindowsCE-EventLogSamplePublisher-Operational"
                  type="Operational"
                  symbol="SAMPLE_PUBLISHER"
                  enabled="true"/>
               </channels>
               <!--Event Templates -->
               <templates>
                  <template tid="MyEventTemplate">
                     <data name="Prop_UnicodeString" inType="win:UnicodeString" />
                     <data name="Prop_UInt32" inType="win:UInt32" />
                     <UserData>
                        <MyEvent2 xmlns="myNs">
                           <Prop_UnicodeString> %1 </Prop_UnicodeString>
                           <Prop_UInt32> %2 </Prop_UInt32>
                        </MyEvent2>
                     </UserData>
                  </template>
               </templates>
               <!--All the Events that can be published by this Publisher -->
               <events>
                  <event value="1"
                     level="win:Informational"
                     template="MyEventTemplate"
                     channel="MyChannel"
                     symbol="PROCESS_SAMPLE_EVENT"
                     message="$(string.Publisher.EventMessage)"/>
               </events>
            </provider>
       </events>
   </instrumentation>
   <localization>
      <resources culture="en-US">
         <stringTable>
            <!--This is how event data can be used as part of a message string -->
            <string id="Publisher.EventMessage"
               value="Prop_UnicodeString=%1;%n
                  Prop_UInt32=%8;%n"/>
         </stringTable>
      </resources>
   </localization>
</instrumentationManifest>

Sample Provider

The following code example shows a sample event log provider that uses the event APIs for registration and logging.

Note

The code, as shown later in this section, must include the header file generated by using the event log XML manifest file.

#include <windows.h>
#include <evntprov.h>
#include <evntcons.h>
#include <evntrace.h>
#include "..\Manifest\MCSample.h"

int WINAPI WinMain(
   HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPWSTR lpCmdLine,
   int nShowCmd
   )
{
   ULONG lResult = NO_ERROR;
   REGHANDLE RegisteredHandle;
   lResult = EventRegister(
      &WINDOWSCE_EVENTLOG_SAMPLE_PUBLISHER,
      NULL,
      NULL,
      &RegisteredHandle);
   if(NO_ERROR != lResult)
   {
      goto exit;
   }
   PEVENT_DATA_DESCRIPTOR pCurrDescriptor = NULL;
   PEVENT_DATA_DESCRIPTOR pDescriptorList = (PEVENT_DATA_DESCRIPTOR)LocalAlloc(LPTR, 2*sizeof(EVENT_DATA_DESCRIPTOR));
   if(NULL == pDescriptorList)
   {
      lResult = ERROR_OUTOFMEMORY;
      goto exit;
   }
   WCHAR *pMyString = L"MyString";
   DWORD MyDWORD = 147;
   pCurrDescriptor = pDescriptorList;
   EventDataDescCreate(pCurrDescriptor, pMyString, 18);
   pCurrDescriptor  = (PEVENT_DATA_DESCRIPTOR)((BYTE *)pDescriptorList + sizeof(EVENT_DATA_DESCRIPTOR));
   EventDataDescCreate(pCurrDescriptor, &MyDWORD, sizeof(DWORD));
   if(EventEnabled(RegisteredHandle, &PROCESS_SAMPLE_EVENT))
   {
      lResult = EventWrite(
         RegisteredHandle,
         &PROCESS_SAMPLE_EVENT,
         2,
         pDescriptorList);
      if(NO_ERROR != lResult)
      {
         goto exit;
      }
   }
   exit: 
   EventUnregister(RegisteredHandle);
   return 0;
}

Sample Subscriber

The following code example shows a sample subscriber to event notifications.

#include <windows.h>
#include <evntprov.h>
#include <evntcons.h>
#include <evntrace.h>

ULONGLONG KeywordMatchAll = 0x0;
ULONGLONG KeywordMatchAny = 0xFFFFFFFFFFFFFFFF;   


int WINAPI WinMain(
   HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPWSTR lpCmdLine,
   int nShowCmd)
{
   HANDLE hSignal = CeEventSubscribe(
      L"Microsoft-WindowsCE-EventLogSamplePublisher-Operational",
      EvtSubscribeToFutureEvents,
      4,
      KeywordMatchAny,
      KeywordMatchAll);
   DWORD dwBufferSize;
   DWORD dwReturnedBytes;
   DWORD dwNumEventData;
   EVENT_DATA_DESCRIPTOR *pDataDescriptor = NULL;
   EVENT_DESCRIPTOR  Descriptor;
   ULONG lResult = NO_ERROR;
   while(WAIT_OBJECT_0 == WaitForSingleObject(hSignal, INFINITE))
   {
      do
      {
         lResult = CeEventRead(
            hSignal,
            &Descriptor,
            NULL,
            0,
            &dwReturnedBytes,
            &dwNumEventData);
            if(Descriptor.Level)
            {
               //If the maximum size of the event is known, the allocation can be done in the setup, rather than allocating each event, as shown below.
               if(!pDataDescriptor)
               {
                  pDataDescriptor = (PEVENT_DATA_DESCRIPTOR)LocalAlloc(
                     LHND,
                     dwReturnedBytes);
                  if(!pDataDescriptor)
                  {
                     lResult = ERROR_OUTOFMEMORY;
                     goto exit;
                  }
                  dwBufferSize = dwReturnedBytes;
               }
               else
               {
                  if(dwBufferSize < dwReturnedBytes)
                  {
                     PEVENT_DATA_DESCRIPTOR pTemp = (PEVENT_DATA_DESCRIPTOR)LocalReAlloc(
                        pDataDescriptor,
                        dwReturnedBytes,
                        LHND);
                     if(NULL == pTemp)
                     {
                        lResult = ERROR_OUTOFMEMORY;
                        goto exit;
                     }
                     dwBufferSize = dwReturnedBytes;
                  }
               }
               lResult = CeEventRead(
                  hSignal,
                  &Descriptor,
                  pDataDescriptor,
                  dwBufferSize,
                  &dwReturnedBytes,
                  &dwNumEventData);
               //Do something with the buffer that has been read.
   RETAILMSG(1,(TEXT("EventLog Subscriber:Got a message!!!! \"%s\"\r\n"),pDataDescriptor->Ptr));

            }
         }
         while (NO_ERROR == CeEventNext(hSignal));
      }
   CeEventClose(hSignal);
   exit:
   return 0;
}#include <windows.h>
#include <evntprov.h>
#include <evntcons.h>
#include <evntrace.h>
#include <winevt.h>
int WINAPI WinMain(
   HINSTANCE hInstance,
   HINSTANCE hPrevInstance,
   LPWSTR lpCmdLine,
   int nShowCmd)
{
   HANDLE hSignal = CeEventSubscribe(
      L"Microsoft-WindowsCE-EventLogSamplePublisher-Operational",
      EvtSubscribeToFutureEvents,
      4,
      0x0,
      0x0);
   DWORD dwBufferSize;
   DWORD dwReturnedBytes;
   DWORD dwNumEventData;
   EVENT_DATA_DESCRIPTOR *pDataDescriptor = NULL;
   EVENT_DESCRIPTOR  Descriptor;
   ULONG lResult = NO_ERROR;
   while(WAIT_OBJECT_0 == WaitForSingleObject(hSignal, INFINITE))
   {
      do
      {
         lResult = CeEventRead(
            hSignal,
            &Descriptor,
            NULL,
            0,
            &dwReturnedBytes,
            &dwNumEventData);
            if(Descriptor.Level)
            {
               //If the maximum size of the event is known, the allocation can be done in the setup, rather than allocating each event, as shown below.
               if(!pDataDescriptor)
               {
                  pDataDescriptor = (PEVENT_DATA_DESCRIPTOR)LocalAlloc(
                     LHND,
                     dwReturnedBytes);
                  if(!pDataDescriptor)
                  {
                     lResult = ERROR_OUTOFMEMORY;
                     goto exit;
                  }
                  dwBufferSize = dwReturnedBytes;
               }
               else
               {
                  if(dwBufferSize < dwReturnedBytes)
                  {
                     PEVENT_DATA_DESCRIPTOR pTemp = (PEVENT_DATA_DESCRIPTOR)LocalReAlloc(
                        pDataDescriptor,
                        dwReturnedBytes,
                        LHND);
                     if(NULL == pTemp)
                     {
                        lResult = ERROR_OUTOFMEMORY;
                        goto exit;
                     }
                     dwBufferSize = dwReturnedBytes;
                  }
               }
               lResult = CeEventRead(
                  hSignal,
                  &Descriptor,
                  pDataDescriptor,
                  dwBufferSize,
                  &dwReturnedBytes,
                  &dwNumEventData);
               //Do something with the buffer that has been read.
            }
         }
         while (NO_ERROR == CeEventNext(hSignal));
      }
   CeEventClose(hSignal);
   exit:
   return 0;
}

See Also

Other Resources

Event Log