c++visual-studio-2022wdmwindows-driver

How to enable warning C6067 during (WDM) Windows driver compilation in VS 2022?


I'm using a WDM driver project in VS 2022. In case of the following code snippet:

extern "C" NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject,
                                      PUNICODE_STRING RegistryPath)
{
    DbgPrint("v=%s", 123);

    return STATUS_SUCCESS;
}

The DbgPrint has an incorrect %s specifier, which will cause that driver to crash.

The VS editor can see it and shows me an underlined warning C6067:

enter image description here

But when I compile it, that warning is not shown and the project compiles successfully, even though the settings for my project are set to "Level4 (/W4)".

Any idea how to enable that warning C6067 during compilation?


Solution

  • The usual MSVC compiler warnings are C4xxx and C5xxx. Warnings with other number format are Code Analysis warnings.

    The /analyze option enables code analysis, which makes the compiler deliberately analyze code semantic for red flags. It has lot more warnings. Some are implemented by the compiler itself, some are available via plugins (like C++ Code Guidelines).

    There's an option /analyze:only to run with code analysis, but without compilation. This makes sense for larger programs, as code analysis is way slower than the usual compilation, so you compile without /analyze at all, and have a scheduled run of /analyze:only on a build server.

    To control large number of various Code Analysis warnings in a more convenient way than pragma or compiler switches, there are .ruleset files. They are in %VSINSTALLDIR%\Team Tools\Static Analysis Tools\Rule Sets. They can be edited via IDE, or as XML files, so that you can create your own .ruleset file, based on an existing one, and suppress any warnings.

    For example if you run the compiler with /analyze:only on the following program, which does not only try to format an integer as a string, but also tries to obtain that integer by indirection of a null pointer:

    #include <stdio.h>
    
    int main()
    {
        int *i = nullptr;
        printf("%s", *i);
    }
    

    You'll have the following output:

    D:\temp2\test.cpp(6) : warning C6067: _Param_(2) in call to 'printf' must be the address of a string. Actual type: 'int'.
    D:\temp2\test.cpp(6) : warning C6011: Dereferencing NULL pointer 'i'. : Lines: 5, 6
    

    If you create the following only_format_string.ruleset file:

    <?xml version="1.0" encoding="utf-8"?>
    <RuleSet Name="Format Strings" Description="I'm only interested in format strings" ToolsVersion="17.0">
      <Rules AnalyzerId="Microsoft.Analyzers.NativeCodeAnalysis" RuleNamespace="Microsoft.Rules.Native">
        <Rule Id="C6067" Action="Warning" />
      </Rules>
    </RuleSet>
    

    And run the conpiler with /analyze:only /analyze:ruleset only_format_string.ruleset, you'll have only C6067, but not C6011.