Visual Studio 2019 - COM in the Kernel : IUknown implementation trouble with DECLARE_STD_UNKNOWN()

Hi,

I’ve just observed a strange behavior when writing a WDMAudio driver with Visual Studio 2019 : the IUnknown implementation is not the expected one for the COM components used in the driver.

A WDMAudio driver heavily uses COM in the Kernel with all the associated IUknown stuff. To ease the development, some helpers exist. One of them (DECLARE_STD_UNKNOWN()) will declares/defines inline the IUknown’s services implementations. When the component (COM object) is instanciated, the IUknown services implementations set in the __vfptr array are not the ones defined by the helper. They are randomly set to others COM componenents’ IUknown implementations.
And of course, this leads to BSOD.

Investigating thhis issue, I’ve found that it’s related to inlined methods’ addresses resolution by the compiler. To overcome this, I’ve expanded the DECLARE_STD_UNKNOWN() as declarations in the .h file and definitions in the .cpp file. Then everything went fine.
But this is a workaround as a the documentation only uses the helpers.

Googling around, I’ve found no one else with this issue.

Could you confirm the issue or is it my mistake ?

Context :

  • Windows 10 - x64
  • Visual Studio 2019 rev 16.10.4
  • WDMAudio driver

I suppose this is a matter of how the compiler handle the address of an inlined method which by nature doesn’t even exist.

The same kind of driver (WDMAudio) is correctly built with the WINDDK 7600.16385.1 toolchain.

I can provide a code sample to reproduce/investigate if needed.

Regards,
Eric.

Oy … the COM stuff in the kernel is always dicey, it really is a house of cards built on jello standing in a stiff wind … if at all possible I would look at using the SimpleAudioSample as a basis for your audio driver … it’s got about the cleanest audio engine stuff that I’ve seen so far, builds with VS 16.10.4 and seems pretty stable under Win10 21H1 and Win11 preview …

Oh come now, that’s utter nonsense. COM in the kernel has the best parts of user-mode COM without the nonsense of funky registry stuff. It’s just virtual function tables. It’s all well understood.

Visual Studio has definitely made some breaking changes in the past several releases regarding things that are now inlined that weren’t before. As long as you use the same compiler everywhere, it should be OK.

Fair statement Mr Roberts, and you definitely have the expertise to back that assertion up … and I do appreciate the reference counting and runtime function assignments that COM brings to the table …

For those without that breadth of knowledge (and I position myself squarely in that camp) the implementation of COM in Visual Studio is confusing at best, the documentation if it’s there obtuse and perfunctory and I would qualify the “well understood” with “by highly experience developers” … hence my first statement, which very admittedly is more hyperbolic than literal …

The OP appears to be running into the same kind of “the black box is broken, now what??” issues that I run into with Visual Studio COM as used in Audio drivers and hence my second statement …

Are you stating that the OP will have better results with the DECLARE_STD_UNKNOWN issues by using the EWDK to compile rather than Visual Studio?

Well, I guess what I’m trying to say is that these kinds of problems happen in both worlds; it’s not the fault of COM-in-the-kernel.

DECLARE_STD_UNKNOWN should only be used in a class that derives directly from CUnknown. More derived classes don’t use it. I have an audio driver that compiles with VS2019 rev 16.2 (cl 19.22.27905) that works fine. It is, of course, possible that they’ve screwed it up since then, but in that case it’s not specifically a kernel problem.

I apologize for being defensive. I was one of the early adopters of C++ in the kernel (1997?), and I’ve spent 25 years defending it.

Ah, didn’t know that about derived classes, great info!

No worries about C++ in Kernel, most of my first production drivers were written using the (much maligned, maybe justifiably so) DriverWorks framework … which with it’s polymorphism, overloading and class constructor/ destructors I thought was nirvana!

I’ve always been a big fan of using C++ paradigms in the Kernel (and lamented the passing of DriverWorks and a return to ANSI99 for many years in kernel land) and really like the COM AddRef/Release model and function QI MS uses for Audio drivers, I just really REALLY wish it wasn’t so hard to track down why things don’t work when it should be so simple …

Don’t worry about being defensive, you like a number of other luminaries on this list well deserve some slack! You’ve forgotten more last week than I’ve learned in decades … :slight_smile: