QueryAll traces microsoft function issue

0

I am using QueryAllTraces Microsoft function in our code and found that when ever actual session count is greater than struct array property size it's throwing

error "access violation".

I need a suggestion regarding below Microsoft code whether session count for-loop at the end of code has error or not, when session count is greater than p sessions struct array size.

If it has error how can I fix dynamically increase struct array size?

Example: session count= 41

link for the Microsoft code: https://docs.microsoft.com/en-us/windows/win32/etw/queryalltraces

#include <windows.h>
#include <stdio.h>
#include <wmistr.h>
#include <evntrace.h>

#define MAX_SESSIONS 40
#define MAX_SESSION_NAME_LEN 1024
#define MAX_LOGFILE_PATH_LEN 1024

void wmain(void)
{
    ULONG status = ERROR_SUCCESS;
    PEVENT_TRACE_PROPERTIES pSessions[MAX_SESSIONS]; // Array of pointers to property structures
    PEVENT_TRACE_PROPERTIES pBuffer = NULL; // Buffer that contains all the property structures
    ULONG SessionCount = 0; // Actual number of sessions started on the computer
    ULONG BufferSize = 0;
    ULONG PropertiesSize = 0;
    WCHAR SessionGuid[50];

    // The size of the session name and log file name used by the
    // controllers are not known, therefore create a properties structure that allows
    // for the maximum size of both.

    PropertiesSize = sizeof(EVENT_TRACE_PROPERTIES) + (MAX_SESSION_NAME_LEN * sizeof(WCHAR)) + (MAX_LOGFILE_PATH_LEN * sizeof(WCHAR));

    BufferSize = PropertiesSize * MAX_SESSIONS;

    pBuffer = (PEVENT_TRACE_PROPERTIES)malloc(BufferSize);

    if (pBuffer) {
        ZeroMemory(pBuffer, BufferSize);

        for (USHORT i = 0; i < MAX_SESSIONS; i++) {
            pSessions[i] = (EVENT_TRACE_PROPERTIES*)((BYTE*)pBuffer + (i * PropertiesSize));
            pSessions[i]->Wnode.BufferSize = PropertiesSize;
            pSessions[i]->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
            pSessions[i]->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + (MAX_SESSION_NAME_LEN * sizeof(WCHAR));
        }
    }
    else {
        wprintf(L"Error allocating memory for properties.\n");
        goto cleanup;
    }

    status = QueryAllTraces(pSessions, (ULONG)MAX_SESSIONS, &SessionCount);

    if (ERROR_SUCCESS == status || ERROR_MORE_DATA == status) {
        wprintf(L"Requested session count, %d. Actual session count, %d.\n\n", MAX_SESSIONS, SessionCount);

        for (USHORT i = 0; i < SessionCount; i++) {
            //sessioncount = 41

            typedef list<wstring> STRING_LIST;
            STRING_LIST sessions;
            wchar_t* pFileName = (wchar_t*)((char*)pSessions[i] + pSessions[i]->LoggerNameOffset); // throwing error-: 0xC0000005: Access violation reading location 0x15C7B6FA.

            sessions.insert(sessions.begin(), pFileName);

            StringFromGUID2(pSessions[i]->Wnode.Guid, SessionGuid, (sizeof(SessionGuid) / sizeof(SessionGuid[0])));

            wprintf(L"Session GUID: %s\nSession ID: %d\nSession name: %s\nLog file: %s\n"
                    L"min buffers: %d\nmax buffers: %d\nbuffers: %d\nbuffers written: %d\n"
                    L"buffers lost: %d\nevents lost: %d\n\n",
                SessionGuid,
                pSessions[i]->Wnode.HistoricalContext,
                (LPWSTR)((char*)pSessions[i] + pSessions[i]->LoggerNameOffset),
                (LPWSTR)((char*)pSessions[i] + pSessions[i]->LogFileNameOffset),
                pSessions[i]->MinimumBuffers,
                pSessions[i]->MaximumBuffers,
                pSessions[i]->NumberOfBuffers,
                pSessions[i]->BuffersWritten,
                pSessions[i]->LogBuffersLost,
                pSessions[i]->EventsLost);
        }
    }
    else {
        wprintf(L"Error calling QueryAllTraces, %d.\n", status);
        goto cleanup;
    }

cleanup:

    if (pBuffer) {
        free(pBuffer);
        pBuffer = NULL;
    }
}
c++
arrays
visual-c++
struct
etw
asked on Stack Overflow Jul 31, 2019 by rremo • edited Jul 31, 2019 by rremo

1 Answer

0

you iterate from i to SessionCount but SessionCount may be more than MAX_SESSIONS.

Your for loop should be something like:

for (USHORT i = 0; i < std::min(SessionCount, MAX_SESSIONS); i++)
answered on Stack Overflow Jul 31, 2019 by Alan Birtles

User contributions licensed under CC BY-SA 3.0