Search code examples
c++winapivisual-c++traceetw

Ellipsis and va_args trick needed


TraceMessage is an WinAPI function with variable number of arguments. It is a tracing function, with a notation similar to printf, which generates a trace message in Windows tracing. The weird part here is that it receive a format string as part of the ellipsis, not as a dedicated argument. It is possible to 'override' this function with a function of my own, which then needs to call TraceMessageVa (which is the same as TraceMessage, just with va_args rather than ellipsis).

So far so good; but now I want to access the traced message using a sprintf-like function, which has the format string out of the ellipsis. Thus I need to
- get the format string argument out of the ellipsis ;
- create a new va_list without the first argument.

Any idea about to how do it? Solutions specific to Visual Studio compiler are also acceptable. Thanks!


Solution

  • With a va_list you can pass it to a function which takes a va_list after having used va_arg on it already to have extracted one or more arguments. The va_list will then act like it "contains" only the rest of the arguments.

    I have no experience with TraceMessage itself, but I've given an example using standard vprintf and a test function. You should be able to adapt as appropriate.

    E.g.

    #include <stdio.h>
    #include <stdarg.h>
    
    void test(int a, ...)
    {
        va_list va;
        const char* x;
    
        va_start(va, a);
        x = va_arg(va, const char*);
    
        vprintf(x, va);
    
        va_end(va);
    }
    
    int main(void)
    {
        test(5, "%d\n", 6);
        return 0;
    }