void etwlogger_log_with_GetLastError()

in src/etwlogger_driver.c [153:202]


void etwlogger_log_with_GetLastError(const char* file, const char* func, int line, const char* format, ...)
{
    DWORD lastError;

    lastError = GetLastError();
    lazyRegisterEventProvider();

    va_list args;
    va_start(args, format);

    char message[LOG_SIZE_REGULAR * (LOG_SIZE_REGULAR>=sizeof(vsnprintf_failure_message))]; /*this construct will generate a compile time error (array of size 0) when LOG_SIZE_REGULAR is not enough to hold even the failure message*/
    {/*scope for constructing the user (format,...)*/
        int vsnprintf_result;
        vsnprintf_result = vsnprintf(message, sizeof(message), format, args);
        if (
            (vsnprintf_result < 0)||
            (vsnprintf_result >= (int)sizeof(message))
            )
        {
            (void)memcpy(message, vsnprintf_failure_message, sizeof(vsnprintf_failure_message));
        }
        else
        {
            /*all fine, message now contains user message*/
        }
    }

    char lastErrorAsString[MESSAGE_BUFFER_SIZE *(MESSAGE_BUFFER_SIZE>sizeof(FormatMessageA_failure_message))];
    if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lastErrorAsString, sizeof(lastErrorAsString), NULL) == 0)
    {
        (void)memcpy(lastErrorAsString, FormatMessageA_failure_message, sizeof(FormatMessageA_failure_message));
    }
    else
    {
        /*remove extraneous newlines from FormatMessageA's output*/
        char* whereAreThey;
        if ((whereAreThey = strchr(lastErrorAsString, '\r')) != NULL)
        {
            *whereAreThey = '\0';
        }
        if ((whereAreThey = strchr(lastErrorAsString, '\n')) != NULL)
        {
            *whereAreThey = '\0';
        }
    }

    perform_EventWriteLogLastError(message, file, func, line, lastErrorAsString);

    va_end(args);
}