I can't compile KMDF driver that uses acx audio class extension.

Hello.
I am a student and I’m studying windows driver development as a hobby. I’m trying to create virtual audio device driver, so I decide to use KMDF and acx audio class extension. I created KMDF driver project and added following code to driver.h and builded it, but I got following error.

code:
#include <acx/km/1.1/acx.h>

error:

1>Building ‘KmdfAudio’ with toolset ‘WindowsKernelModeDriver10.0’ and the ‘Universal’ target platform.
1>Stamping x64\Debug\KmdfAudio.inf
1>Stamping [Version] section with DriverVer=10/19/2023,21.27.43.441
1>Device.c
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\km\acx\km\1.1\AcxFuncEnum.h(114,1): fatal error C1189: #error: ACX_VERSION_MAJOR is not defined
1>Driver.c
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\km\acx\km\1.1\AcxFuncEnum.h(114,1): fatal error C1189: #error: ACX_VERSION_MAJOR is not defined
1>Queue.c
1>C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\km\acx\km\1.1\AcxFuncEnum.h(114,1): fatal error C1189: #error: ACX_VERSION_MAJOR is not defined

In Visual Studio, I configured KMDF Version Major as 1, Minor(Target Version) as 33 and Minor(Minimum Required) as 33. I have no experience in driver development and apologize if this is a very elementary mistake.

You need to define ACX_VERSION_MAJOR and ACX_VERSION_MINOR in the Globals PropertyGroup of your VS project file (the .vcxproj file.) Like this:

<PropertyGroup Label="Globals">
    <ACX_VERSION_MAJOR>1</ACX_VERSION_MAJOR>
    <ACX_VERSION_MINOR>1</ACX_VERSION_MINOR>

@Mark_Roddy said:
You need to define ACX_VERSION_MAJOR and ACX_VERSION_MINOR in the Globals PropertyGroup of your VS project file (the .vcxproj file.) Like this:

<PropertyGroup Label="Globals">
    <ACX_VERSION_MAJOR>1</ACX_VERSION_MAJOR>
    <ACX_VERSION_MINOR>1</ACX_VERSION_MINOR>

It doesn’t works for me, but I added the property in PreprocessorDefinition and it worked! I struggled this problem for a whole day, your advice helped me a lot, thank you!

I hope you will report on your progress. There is great interest in virtual audio drivers, but they have traditionally been very messy to create. If you find this to be a viable path, we’d appreciate hearing about it.

99% sure the msbuild properties do more than define the constants. They also add the specified version of ACX include directory to the INCLUDE path and add the version specific ACX lib to the linker command line. Are you able to successfully link a driver and have it run purely with #defines and not the msbuild properties?

I noticed that these ways let me able to compile only #include header, when I use ACX in my driver, it fail to compile.
I added acx\km\1.1\acxstub.lib to the linker dependency, and successed to compile.

include <acx/km/1.1/acx.h>
link acx\km\1.1\acxstub.lib

exactly my point. Either you are not using the right method to configure using the ACX library or the WDK is not properly implementing the PropertyGroup pattern. My guess it is your mistake, not WDF. If properly configured using the properties it would be

#include “acx.h”

and the library would be automatically added to the linker command line without manual editing.

The compile section in the sample vcxproj msbuild file ignores the global properties and sets ACX_VERSION_MAJOR and ACX_VERSION_MINOR again. passing them as preprocessor definitions (sigh).

But ignoring that, it also adds the directory include path for acx correctly using the global properties. You should add the to your vcxproj file for each of your build configuration itemdefinitiongroup sections. You can do this in the VS gui, but I never bother, it is much easier to just edit the file.

  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WppEnabled>true</WppEnabled>
      <WppRecorderEnabled>true</WppRecorderEnabled>
      <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">..\..\common\trace_macros.h</WppScanConfigurationData>
      <WppKernelMode>true</WppKernelMode>
      <AdditionalIncludeDirectories>$(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km\$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR);..\..\common;..\..\inc;..\..\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile> 

@Tim_Roberts said:
I hope you will report on your progress. There is great interest in virtual audio drivers, but they have traditionally been very messy to create. If you find this to be a viable path, we’d appreciate hearing about it.

Sure!

@Doron_Holan said:
99% sure the msbuild properties do more than define the constants. They also add the specified version of ACX include directory to the INCLUDE path and add the version specific ACX lib to the linker command line. Are you able to successfully link a driver and have it run purely with #defines and not the msbuild properties?

I tried to add following code to Driver.h and successfully compiled the driver without msbuild property.

#define ACX_VERSION_MAJOR 1
#define ACX_VERSION_MINOR 1
#include <acx/km/1.1/acx.h>

> @Mark_Roddy said: > The compile section in the sample vcxproj msbuild file ignores the global properties and sets ACX_VERSION_MAJOR and ACX_VERSION_MINOR again. passing them as preprocessor definitions (sigh). > > But ignoring that, it also adds the directory include path for acx correctly using the global properties. You should add the to your vcxproj file for each of your build configuration itemdefinitiongroup sections. You can do this in the VS gui, but I never bother, it is much easier to just edit the file. > > true true …..\common\trace_macros.h true $(SDK_INC_PATH);$(DDK_INC_PATH)\acx\km$(ACX_VERSION_MAJOR).$(ACX_VERSION_MINOR);…..\common;…..\inc;…..\shared;%(AdditionalIncludeDirectories) ACX_VERSION_MAJOR=1;ACX_VERSION_MINOR=1;KMDF_VERSION_MAJOR=1;KMDF_VERSION_MINOR=31;%(PreprocessorDefinitions)

Thank you, I’ll try!