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;
}
}
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++)
User contributions licensed under CC BY-SA 3.0