Search code examples
winapiwindowrpcetwlogman

How to trace event logs from provider "Microsoft-Windows-RPC" programmatically


I want to create a program that will trace event logs from the provider "Microsoft-Windows-RPC".

The program logman.exe by Microsoft is doing it like that:

logman start RPC_ONLY -p Microsoft-Windows-RPC -ets 

When done, you can capture the logs like that:

tracerpt RPC_ONLY.etl -o RPC_ONLY.evtx -of EVTX
logman stop RPC_ONLY -ets

I want my program to be able to trace it like logman does but I didn't understand how.
Is there a function that I can "tell" windows that I want it to start tracing events related to Microsoft-Windows-RPC?


Solution

  • According to Example that Creates a Session and Enables a Manifest-based or Classic Provider, I have traced Microsoft-Windows-RPC events successfully with some changes. With log.etl, you can then Retrieve Event Data.

    #include <windows.h>
    #include <stdio.h>
    #include <conio.h>
    #include <strsafe.h>
    #include <wmistr.h>
    #include <evntrace.h>
    
    #define LOGFILE_PATH L"C:\\log.etl"
    #define LOGSESSION_NAME L"My Event Trace Session"
    
    // GUID that identifies your trace session.
    // Remember to create your own session GUID.
    
    // {AE44CB98-BD11-4069-8093-770EC9258A12}
    //static const GUID SessionGuid = { 0xae44cb98, 0xbd11, 0x4069, { 0x80, 0x93, 0x77, 0xe, 0xc9, 0x25, 0x8a, 0x12 } };
    
    // GUID that identifies the provider that you want
    // to enable to your session.
    
    // {D8909C24-5BE9-4502-98CA-AB7BDC24899D}
    /*
    name: Microsoft-Windows-RPC
    guid: 6ad52b32-d609-4be9-ae07-ce8dae937e39
    */
    static const GUID ProviderGuid =
    { 0x6ad52b32, 0xd609, 0x4be9, {0xae, 0x07, 0xce, 0x8d, 0xae, 0x93, 0x7e, 0x39 } };
    
    void wmain(void)
    {
        ULONG status = ERROR_SUCCESS;
        TRACEHANDLE SessionHandle = 0;
        EVENT_TRACE_PROPERTIES* pSessionProperties = NULL;
        ULONG BufferSize = 0;
        BOOL TraceOn = TRUE;
    
        // Allocate memory for the session properties. The memory must
        // be large enough to include the log file name and session name,
        // which get appended to the end of the session properties structure.
    
        BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGFILE_PATH) + sizeof(LOGSESSION_NAME);
        pSessionProperties = (EVENT_TRACE_PROPERTIES*)malloc(BufferSize);
        if (NULL == pSessionProperties)
        {
            wprintf(L"Unable to allocate %d bytes for properties structure.\n", BufferSize);
            goto cleanup;
        }
    
        // Set the session properties. You only append the log file name
        // to the properties structure; the StartTrace function appends
        // the session name for you.
    
        ZeroMemory(pSessionProperties, BufferSize);
        pSessionProperties->Wnode.BufferSize = BufferSize;
        pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
        pSessionProperties->Wnode.ClientContext = 1; //QPC clock resolution
        //pSessionProperties->Wnode.Guid = SessionGuid;
        pSessionProperties->Wnode.Guid = {};
        pSessionProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL;
        pSessionProperties->MaximumFileSize = 1;  // 1 MB
        pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
        pSessionProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGSESSION_NAME);
        StringCbCopy((LPWSTR)((char*)pSessionProperties + pSessionProperties->LogFileNameOffset), sizeof(LOGFILE_PATH), LOGFILE_PATH);
    
        // Create the trace session.
    
        status = StartTrace((PTRACEHANDLE)&SessionHandle, LOGSESSION_NAME, pSessionProperties);
        if (ERROR_SUCCESS != status)
        {
            wprintf(L"StartTrace() failed with %lu\n", status);
            goto cleanup;
        }
    
        // Enable the providers that you want to log events to your session.
    
        status = EnableTraceEx2(
            SessionHandle,
            (LPCGUID)&ProviderGuid,
            EVENT_CONTROL_CODE_ENABLE_PROVIDER,
            TRACE_LEVEL_INFORMATION,
            0,
            0,
            0,
            NULL
        );
    
        if (ERROR_SUCCESS != status)
        {
            wprintf(L"EnableTrace() failed with %lu\n", status);
            TraceOn = FALSE;
            goto cleanup;
        }
    
        wprintf(L"Run the provider application. Then hit any key to stop the session.\n");
        _getch();
    
    cleanup:
    
        if (SessionHandle)
        {
            if (TraceOn)
            {
                status = EnableTraceEx2(
                    SessionHandle,
                    (LPCGUID)&ProviderGuid,
                    EVENT_CONTROL_CODE_DISABLE_PROVIDER,
                    TRACE_LEVEL_INFORMATION,
                    0,
                    0,
                    0,
                    NULL
                );
            }
    
            status = ControlTrace(SessionHandle, LOGSESSION_NAME, pSessionProperties, EVENT_TRACE_CONTROL_STOP);
    
            if (ERROR_SUCCESS != status)
            {
                wprintf(L"ControlTrace(stop) failed with %lu\n", status);
            }
        }
    
        if (pSessionProperties)
        {
            free(pSessionProperties);
            pSessionProperties = NULL;
        }
    }
    

    enter image description here